clean up last import
authorYves Fischer <[email protected]>
Sun, 26 Oct 2008 16:40:10 +0000 (26 17:40 +0100)
committerYves Fischer <[email protected]>
Sun, 26 Oct 2008 16:40:10 +0000 (26 17:40 +0100)
28 files changed:
pgworksheet/AUTHORS [deleted file]
pgworksheet/LICENSE.txt [deleted file]
pgworksheet/README [deleted file]
pgworksheet/applications/pgworksheet.desktop [deleted file]
pgworksheet/locale/fr/LC_MESSAGES/pgworksheet.mo [deleted file]
pgworksheet/locale/ja/LC_MESSAGES/pgworksheet.mo [deleted file]
pgworksheet/pgw/DBConnection.py [deleted file]
pgworksheet/pgw/Execute.py [deleted file]
pgworksheet/pgw/Lexical.py [deleted file]
pgworksheet/pgw/MyPgSQL.py [deleted file]
pgworksheet/pgw/RunSQL.py [deleted file]
pgworksheet/pgw/Syntax.py [deleted file]
pgworksheet/pgw/UI.py [deleted file]
pgworksheet/pgw/Undo.py [deleted file]
pgworksheet/pgw/__init__.py [deleted file]
pgworksheet/pgworksheet [deleted file]
pgworksheet/pixmaps/pgworksheet.png [deleted file]
pgworksheet/pixmaps/pgworksheet/about.png [deleted file]
pgworksheet/pixmaps/pgworksheet/connect.png [deleted file]
pgworksheet/pixmaps/pgworksheet/disconnect.png [deleted file]
pgworksheet/pixmaps/pgworksheet/pgworksheet-32.png [deleted file]
pgworksheet/pixmaps/pgworksheet/pgworksheet.ico [deleted file]
pgworksheet/pixmaps/pgworksheet/pgworksheet.png [deleted file]
pgworksheet/pixmaps/pgworksheet/pgworksheet.xcf [deleted file]
pgworksheet/setup.py [deleted file]
pgworksheet_yvesf/locale/pgworksheet.pot
pgworksheet_yvesf/pgworksheet.py [changed mode: 0644->0755]
pgworksheet_yvesf/plugins/sidebar/FunctionBrowser.py

diff --git a/pgworksheet/AUTHORS b/pgworksheet/AUTHORS
deleted file mode 100644 (file)
index 096c148..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Henri Michelon hmichelon at e-cml.org
diff --git a/pgworksheet/LICENSE.txt b/pgworksheet/LICENSE.txt
deleted file mode 100644 (file)
index 5b6e7c6..0000000
+++ /dev/null
@@ -1,340 +0,0 @@
-                   GNU GENERAL PUBLIC LICENSE
-                      Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                           Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-\f
-                   GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-\f
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-\f
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-\f
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-                           NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-                    END OF TERMS AND CONDITIONS
-\f
-           How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/pgworksheet/README b/pgworksheet/README
deleted file mode 100644 (file)
index 6f685f2..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-== General Informations ==
-
-PgWorksheet is a simple GUI frontend to PostgreSQL 
-for executing SQL queries without using the psql command line tool.
-
-More informations on : http://pgworksheet.projects.postgresql.org/
-
-== Operating systems ==
-PgWorksheet is certified to run on the following operating systems:
-    * FreeBSD
-    * Linux Ubuntu 
-    * Linux Fedora
-    * Linux Mandriva
-    * Microsoft Windows XP
-
-== Depencies ==
-PgWorksheet requires the following softwares to run :
-    * Python 2.4 or better
-    * Python GTK+ 2.6 or better
-    * python-pgsql 0.9.7 (or better) or pyPgSQL
-
-== Installation ==
-Please refers to http://pgworksheet.projects.postgresql.org/install.html for installation instructions.
diff --git a/pgworksheet/applications/pgworksheet.desktop b/pgworksheet/applications/pgworksheet.desktop
deleted file mode 100644 (file)
index a2c16da..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-[Desktop Entry]
-Name=PgWorksheet
-GenericName=
-Comment=PostgreSQL SQL Tool
-Categories=Application;Development;Databases;
-Encoding=UTF-8
-Exec=pgworksheet
-Icon=pgworksheet.png
-StartupNotify=true
-Terminal=false
-Type=Application
diff --git a/pgworksheet/locale/fr/LC_MESSAGES/pgworksheet.mo b/pgworksheet/locale/fr/LC_MESSAGES/pgworksheet.mo
deleted file mode 100644 (file)
index 738dfdf..0000000
Binary files a/pgworksheet/locale/fr/LC_MESSAGES/pgworksheet.mo and /dev/null differ
diff --git a/pgworksheet/locale/ja/LC_MESSAGES/pgworksheet.mo b/pgworksheet/locale/ja/LC_MESSAGES/pgworksheet.mo
deleted file mode 100644 (file)
index 2beed87..0000000
Binary files a/pgworksheet/locale/ja/LC_MESSAGES/pgworksheet.mo and /dev/null differ
diff --git a/pgworksheet/pgw/DBConnection.py b/pgworksheet/pgw/DBConnection.py
deleted file mode 100644 (file)
index 8a0d4f8..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-# -*- coding: latin-1; -*-
-#
-# PgWorksheet - PostgreSQL Front End
-# http://pgworksheet.projects.postgresql.org/
-#
-# Copyright Â© 2004-2008 Henri Michelon & CML http://www.e-cml.org/
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details (read LICENSE.txt).
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# $Id: DBConnection.py,v 1.24 2008/03/13 10:46:24 hmichelon Exp $
-#
-import string
-import sys
-try:
-    import pgsql
-    havepgsql = True
-except:
-    try:
-        from mx import DateTime
-        from pyPgSQL import libpq
-        import MyPgSQL
-       havepgsql = False
-    except:
-       msg = _("please install the python-pgsql or pyPgSQL (with mxDateTime) packages")
-       print(msg)
-       import gtk
-       dialog = gtk.MessageDialog(None,
-                                  gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
-                                  gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, msg)
-       result = dialog.run()
-       dialog.destroy()
-       sys.exit(0)
-
-
-class DBConnection:
-  """Database connection/deconnection and query execution"""
-
-  def __init__(self, host = None, port = None, db = None, user = None, password = None):
-    """Try to connect to a database"""
-    if (havepgsql) :
-        self.connect_pgsql(host, port, db, user, password)
-    else :
-        self.connect_pypgsql(host, port, db, user, password)
-
-  def connect_pypgsql(self, host = None, port = None, db = None, user = None, password = None):
-    dsn = ""
-    if (host is not None): dsn = host
-    dsn = dsn + ":"
-    if (port is not None): dsn = dsn + str(port)
-    dsn = dsn + ":"
-    if (db is not None): dsn = dsn + db
-    dsn = dsn + ":"
-    if (user is not None): dsn = dsn + user
-    dsn = dsn + ":"
-    if (password is not None): dsn = dsn + password
-    try:
-      self.db = MyPgSQL.connect(dsn)
-      self.db.autocommit = 1
-      self.host = host
-      self.port = port
-      self.database = db
-      self.user = user
-      self.password = password
-    except libpq.DatabaseError:
-      self.db = None
-
-
-  def connect_pgsql(self, host = None, port = None, db = None, user = None, password = None):
-    try:
-        if (port is not None) : 
-            self.db = pgsql.connect(db, user, password, host, int(port))
-        else :
-            self.db = pgsql.connect(db, user, password, host)
-        self.host = host
-        self.port = port
-        self.database = db
-        self.user = user
-        self.password = password
-    except pgsql.ProgrammingError:
-        self.db = None
-
-
-  def pgversion(self):
-    if (self.is_connected() and not havepgsql):
-     v = string.split(str(self.db.version), ',')
-     return v.pop(0)
-    return ''
-
-
-  def query(self, sql):
-      if (havepgsql):
-          return self.query_pgsql(sql)
-      else:
-          return self.query_pypgsql(sql)
-
-
-  def query_pypgsql(self, sql):
-    """Execute a query and return the corresponding DB-API cursor."""
-    if not self.is_connected() : return None
-    cursor = self.db.cursor()
-    try:
-      cursor.execute("SET CLIENT_ENCODING TO 'UTF-8'")
-      cursor.execute(sql)
-    except libpq.OperationalError, msg:
-      cursor.close()
-      return { 'error' : str(msg), 'notices' : self.db.notices }
-    return { 'cursor' : cursor, 'notices' : self.db.notices }
-  
-  def query_pgsql(self, sql):
-    """Execute a query and return the corresponding DB-API cursor."""
-    if not self.is_connected() : return None
-    cursor = self.db.cursor()
-    try:
-      cursor.execute("SET CLIENT_ENCODING TO 'UTF-8'")
-      cursor.execute(sql)
-      self.db.commit()
-    except pgsql.ProgrammingError, msg:
-      cursor.close()
-      return { 'error' : str(msg), 'notices' : self.db.notices }
-    return { 'cursor' : cursor, 'notices' : self.db.notices }
-  
-
-  def commit(self):
-    if not self.is_connected() : return
-    self.db.commit()
-
-
-  def is_connected(self):
-    return (self.db != None)
-
-
-  def disconnect(self):
-    if not self.is_connected() : return
-    self.db.close()
-    self.db = None
diff --git a/pgworksheet/pgw/Execute.py b/pgworksheet/pgw/Execute.py
deleted file mode 100644 (file)
index 98f4c02..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-# -*- coding: latin-1; -*-
-#
-# PgWorksheet - PostgreSQL Front End
-# http://pgworksheet.projects.postgresql.org/
-#
-# Copyright Â© 2004-2008 Henri Michelon & CML http://www.e-cml.org/
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details (read LICENSE.txt).
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# $Id: Execute.py,v 1.28 2008/03/12 20:26:23 hmichelon Exp $
-#
-import os
-import sys
-import popen2
-import string
-import gtk
-
-import pgw
-import pgw.Lexical
-
-
-class Execute:
-  """SQL query and psql commands handling"""
-
-
-  def __init__(self, db):
-    self.db = db
-    self.lexical = pgw.Lexical.Lexical()
-
-
-  def execute_one(self, sql):
-    """Execute one query"""
-    if (len(sql) > 0) :
-      # psql commands
-      if (sql[0] == '\\'):
-        sql = string.replace(sql, '\\\\', '\\')
-        if (pgw.mswindows()):
-          cmd = "psql.exe"
-          sql = string.strip(sql)
-        else:
-          cmd = "psql"
-        if (self.db.user is not None):
-          cmd += ' -U "' + self.db.user + '"'
-        if (self.db.host is not None):
-          cmd += ' -h "' + self.db.host + '"'
-        if (self.db.port is not None):
-          cmd += ' -p ' + self.db.port
-        if (self.db.database is not None):
-          cmd += ' -d "' + self.db.database + '"'
-        cmd += ' -c "' + sql + '"'
-        if (self.db.password is not None):
-          os.putenv("PGPASSWORD", self.db.password)
-        #os.putenv("PGCLIENTENCODING", pgw.get_user_encoding())
-        output, input = popen2.popen4(cmd)
-        result = output.read()
-        output.close()
-        input.close()
-        #os.putenv("PGCLIENTENCODING", "")
-        os.putenv("PGPASSWORD", "")
-        return { 'text' : result }
-      else:
-        # SQL query
-        return self.db.query(sql)
-
-
-  def execute(self, buffer):
-    """Execute SQL queries or psql commands"""
-    if not self.db.is_connected() : return
-    # SQL query
-    sqls = self.split(buffer)
-    if (len(sqls) > 1):
-      # multiple queries
-      results = []
-      for sql in sqls:
-        sql = string.strip(sql)
-        if (len(sql) > 0):
-          results.append(self.execute_one(sql))
-      if (len(results) == 1):
-        return results[0]
-      return results  
-    else:
-      # unique query
-      return self.execute_one(sqls[0])
-
-    
-  def split(self, oldbuffer):
-    """Split multiple queries"""
-    # a new textbuffer, because we don't want to modify the original
-    buffer = gtk.TextBuffer()
-    buffer.set_text(oldbuffer.get_text(oldbuffer.get_start_iter(),
-                                       oldbuffer.get_end_iter()))
-    # filter comments
-    tokens = self.lexical.analyse(buffer, buffer.get_start_iter(),
-                                  buffer.get_end_iter())
-    for token in tokens:
-      if (token.token == 'comment'):
-        buffer.delete(token.start_iter, token.end_iter)
-
-    # restart without the comments
-    buffer.set_text(buffer.get_text(buffer.get_start_iter(),
-                                    buffer.get_end_iter()))
-    start = buffer.get_start_iter()
-    end = buffer.get_end_iter()
-    tokens = self.lexical.analyse(buffer, start, end)
-
-    # create a list of queries
-    sql = buffer.get_text(start, end)
-    parts = []
-    stop = start
-    while (len(tokens) > 0):
-      token = tokens.pop(0)
-      if (token.token == 'psql'):
-        i = token.start_iter
-        i.backward_char()
-        parts.append(buffer.get_text(stop, i))
-        parts.append(token.value)
-        stop = token.end_iter
-      elif (token.value == ';'):
-        i = token.start_iter
-        parts.append(buffer.get_text(stop, i))
-        stop = token.end_iter
-    if (stop != end):
-      parts.append(buffer.get_text(stop, end))
-    return parts
diff --git a/pgworksheet/pgw/Lexical.py b/pgworksheet/pgw/Lexical.py
deleted file mode 100644 (file)
index 9530d08..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: latin-1; -*-
-#
-# PgWorksheet - PostgreSQL Front End
-# http://pgworksheet.projects.postgresql.org/
-#
-# Copyright Â© 2004-2008 Henri Michelon & CML http://www.e-cml.org/
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details (read LICENSE.txt).
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# $Id: Lexical.py,v 1.9 2008/03/12 20:26:23 hmichelon Exp $
-#
-
-# http://www.postgresql.org/docs/8.0/static/sql-syntax.html
-
-# basic characters sets
-SPACES = [ ' ', '\t', '\n' ]
-DIGITS = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ]
-NUMERIC = DIGITS + [ 'e', '.', '+', '-' ]
-OPERATOR_CHARS = [ '+', '-', '*', '/', '<', '>', '=', '~', '!', \
-                   '@', '#', '%', '^', '&', '|', '`', '?' ]
-SPECIAL_CHARS = [ '(', ')', '[', ']', ',', ';', ':', '*', '.' ]
-OPERATORS = OPERATOR_CHARS + SPECIAL_CHARS
-
-# not the first character of an identifier
-NOT_IDENT_START = SPECIAL_CHARS + OPERATOR_CHARS + DIGITS + [ '$' ]
-# not a character of an identifier
-NOT_IDENT_CHAR = SPECIAL_CHARS + OPERATOR_CHARS + SPACES + [ "'" ]
-# not a character of a dollar quoted string
-NOT_DOLLAR_QUOTED = [ '$' ] + SPACES
-
-
-class Token:
-
-  def __init__(self, token, start_iter, end_iter, value=None):
-    self.token = token
-    self.start_iter = start_iter
-    self.end_iter = end_iter
-    self.value = value
-
-
-class Eob:
-  """End of Buffer Exception"""
-
-
-class Lexical:
-  """Simplified lexical analyser"""
-
-  def analyse(self, buffer, start, end):
-    """Run the lexical analyser"""
-    self.buffer = buffer
-    self.current = start.copy()
-    self.tokens = [];
-    try:
-      self.lexical_analyser(end.copy())
-    except Eob:
-      pass
-    return self.tokens
-
-
-  def next_char(self):
-    """Returns the next character to analyse"""
-    if (self.current.is_end()):
-      raise Eob()
-    c = self.current.get_char()
-    self.current.forward_char()
-    return c
-  
-
-  def skip_spaces(self, c):
-    """Skips everything that looks like a space/tab/etc..."""
-    while (c in SPACES):
-      c = self.next_char()
-    return c  
-
-
-  def string(self):
-    """Single quoted strings"""
-    start = self.current.copy()
-    start.backward_char()
-    prev = None
-    c = self.next_char()
-    try:
-      while (True):
-        if ((c == "'") and (prev != '\\')): # a single quote in the string...
-          c = self.next_char()
-          if (c != "'"):
-            break
-        prev = c
-        c = self.next_char()
-    except Eob:    
-      end = self.current.copy()
-      self.tokens.append(Token('string', start, end))
-      raise
-    end = self.current.copy()
-    end.backward_char()
-    self.tokens.append(Token('string', start, end))
-    return c
-
-  
-  def dollar_string(self):
-    """Dollar-quoted strings"""
-    # first bound
-    start = self.current.copy()
-    start.backward_char()
-    c = self.next_char()
-    string_tag = ''
-    try:
-      while (c not in NOT_DOLLAR_QUOTED):
-        string_tag = string_tag + c
-        c = self.next_char()
-    except Eob:
-      end = self.current.copy()
-      self.tokens.append(Token('identifier', start, end, string_tag.upper()))
-      raise
-    end = self.current.copy()
-    end.backward_char()
-    if (c != '$'):
-      self.tokens.append(Token('identifier', start, end, string_tag.upper()))
-      return c
-    self.tokens.append(Token('dollarquote', start, end, string_tag.upper()))
-    
-    # string content
-    start = self.current.copy()
-    try:
-      c = self.next_char()
-    except Eob:  
-      end = self.current.copy()
-      self.tokens.append(Token('identifier', start, end, string_tag.upper()))
-      raise
-    try:
-      while (True):
-        if (c == '$'):
-          string_end = self.current.copy()
-          c = self.next_char()
-          s = ''
-          while (c not in NOT_DOLLAR_QUOTED):
-            s = s + c
-            c = self.next_char()
-          if (s == string_tag):
-            string_end.backward_char()
-            self.tokens.append(Token('string', start, string_end))
-            end = self.current.copy()
-            end.backward_char()
-            self.tokens.append(Token('dollarquote', start, end, s.upper()))
-            return c
-        else:
-          c = self.next_char()
-    except Eob:
-      end = self.current.copy()
-      self.tokens.append(Token('string', start, end))
-      raise
-    end = self.current.copy()
-    end.backward_char()
-    self.tokens.append(Token('string', start, end))
-    return c
-
-
-  def bit_string_constant(self, start):
-    """Binary and Hexadecimal numeric constants using strings"""
-    c = self.next_char()
-    if (c == "'"):
-      c = self.next_char()
-      start = self.current.copy()
-      start.backward_char()
-      start.backward_char()
-      start.backward_char()
-      while (c != "'"):
-        c = self.next_char()
-      end = self.current.copy()
-      self.tokens.append(Token('numeric_constant', start, end))
-      return self.next_char()
-    else:
-      return self.identifier(c, start)
-
-
-  def identifier(self, c, ident = ''):
-    """An identifier, keyword, type name, etc..."""
-    start = self.current.copy()
-    for i in range(0, len(ident) + 1):
-      start.backward_char()
-    try:
-      while (c not in NOT_IDENT_CHAR):
-        ident = ident + c
-        c = self.next_char()
-    except Eob:    
-      end = self.current.copy()
-      self.tokens.append(Token('identifier', start, end, ident.upper()))
-      raise
-    end = self.current.copy()
-    end.backward_char()
-    self.tokens.append(Token('identifier', start, end, ident.upper()))
-    return c  
-
-
-  def numeric(self, c):
-    """A numeric constant"""
-    start = self.current.copy()
-    start.backward_char()
-    try:
-      while (c in NUMERIC):
-        c = self.next_char()
-    except Eob:
-      end = self.current.copy()
-      self.tokens.append(Token('numeric_constant', start, end))
-      raise
-    end = self.current.copy()
-    end.backward_char()
-    self.tokens.append(Token('numeric_constant', start, end))
-    return c  
-
-
-  def simple_comment(self):
-    """One line comment using --"""
-    start = self.current.copy()
-    start.backward_char()
-    start.backward_char()
-    c = self.next_char()
-    try:
-      while (c != '\n'):
-        c = self.next_char()
-    except Eob:    
-      end = self.current.copy()
-      self.tokens.append(Token('comment', start, end))
-      raise
-    end = self.current.copy()
-    self.tokens.append(Token('comment', start, end))
-
-
-  def comment(self):
-    """Multi lines comments using /* */"""
-    start = self.current.copy()
-    start.backward_char()
-    start.backward_char()
-    c = self.next_char()
-    prev = None
-    nested = 0
-    try:
-      while (True):
-        if (c == '*'):
-          c = self.next_char()
-          if (prev == '/'):
-            nested = nested + 1
-            continue
-          if (c == '/'):
-            if (nested == 0):
-              c = self.next_char()
-              break
-            else:
-              nested = nested - 1
-          else:
-            prev = c
-            continue
-        prev = c
-        c = self.next_char()
-    except Eob:    
-      end = self.current.copy()
-      self.tokens.append(Token('comment', start, end))
-      raise
-    end = self.current.copy()
-    end.backward_char()
-    self.tokens.append(Token('comment', start, end))
-    return c
-
-
-  def psql(self):
-    """A PgSQL Command"""
-    start = self.current.copy()
-    start.backward_char()
-    c = self.next_char()
-    cmd = '\\'
-    try:
-      while (c != '\n') and (c != ';'):
-        cmd = cmd + c
-        c = self.next_char()
-    except:
-      end = self.current.copy()
-      self.tokens.append(Token('psql', start, end, cmd))
-      raise
-    end = self.current.copy()
-    self.tokens.append(Token('psql', start, end, cmd))
-
-
-  def lexical_analyser(self, fin):
-    """A simplified lexical analyser"""
-    c = self.next_char()
-    while (self.current.compare(fin) <= 0):
-      c = self.skip_spaces(c)
-      # Multi lines comments
-      if (c == '/'):
-        c = self.next_char()
-        if (c == '*'):
-          c = self.comment()
-          continue
-        else:
-          self.current.backward_char()
-      # One line comments
-      elif (c == '-'):
-        c = self.next_char()
-        if (c == '-'):
-          self.simple_comment()
-        else:
-          self.current.backward_char()
-      # psql commands
-      elif (c == '\\'):
-        self.psql()
-      # numeric  
-      elif (c in DIGITS):
-        c = self.numeric(c)
-        continue
-      # bit strings
-      elif (c == 'B') or (c == 'b') or (c == 'H') or (c == 'h'):
-        c = self.bit_string_constant(c)
-        continue
-      # strings
-      elif (c == "'"):
-        c = self.string()
-        continue
-      # dollar-quoted strings
-      elif (c == '$'):
-        c = self.dollar_string()
-        continue
-      # numeric
-      elif (c == '.'):
-        c = self.next_char()
-        if (c in DIGITS):
-          self.current.backward_char()
-          c = self.numeric(self.current.get_char())
-          continue
-      # quoted identifiers  
-      elif (c == '"'):
-        c = self.next_char()
-        while (c != '"'):
-          c = self.next_char()
-      # operators    
-      elif (c in OPERATORS):
-        start = self.current.copy()
-        start.backward_char()
-        end = self.current.copy()
-        self.tokens.append(Token('operator', start, end, c))
-      # everything else
-      elif (c not in NOT_IDENT_START):
-        c = self.identifier(c)
-        continue
-      c = self.next_char()
diff --git a/pgworksheet/pgw/MyPgSQL.py b/pgworksheet/pgw/MyPgSQL.py
deleted file mode 100644 (file)
index a9f3cd4..0000000
+++ /dev/null
@@ -1,3257 +0,0 @@
-#ident "@(#) $Id: MyPgSQL.py,v 1.2 2004/11/24 10:31:07 hmichelon Exp $"
-# vi:set sw=4 ts=8 showmode ai:
-#--(H+)-----------------------------------------------------------------+
-# Name:                PgSQL.py                                                |
-#                                                                      |
-# Description: This file implements a Python DB-API 2.0 interface to   |
-#              PostgreSQL.                                             |
-#=======================================================================|
-# Copyright 2000 by Billy G. Allie.                                    |
-# All rights reserved.                                                 |
-#                                                                      |
-# Permission to use, copy, modify, and distribute this software and its        |
-# documentation for any purpose and without fee is hereby granted, pro-        |
-# vided that the above copyright notice appear in all copies and that  |
-# both that copyright notice and this permission notice appear in sup- |
-# porting documentation, and that the copyright owner's name not be    |
-# used in advertising or publicity pertaining to distribution of the   |
-# software without specific, written prior permission.                 |
-#                                                                      |
-# THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
-# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS.  IN        |
-# NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR  |
-# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS  |
-# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE        |
-# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE   |
-# USE OR PERFORMANCE OF THIS SOFTWARE.                                 |
-#=======================================================================|
-# Revision History:                                                    |
-#                                                                      |
-# Date      Ini Description                                            |
-# --------- --- ------------------------------------------------------- |
-# 05JUL2003 bga - Fixed a problem with PgNumeric where an exception can        |
-#                be thrown if the stated scale and precision of the    |
-#                returned in the first result row does not match later |
-#                rows.                                                 |
-# 26JUN2003 bga - Applied patch from Laurent Pinchart to allow _quote  |
-#                to correctly process objects that are sub-classed     |
-#                from String and Long types.                           |
-# 05JUN2003 bga - Change the name of the quoting function back to      |
-#                _quote. Variables named like __*__ should be restrict |
-#                to system names.                                      |
-# 02JUN2003 bga - PgTypes is now hashable.  repr() of a PgType will now        |
-#                return the repr() of the underlying OID.              |
-#              - Connection.binary() will now fail if autocommit is    |
-#                enabled.                                              |
-#              - Connection.binary() will no longer commit the trans-  |
-#                action after creating the large object.  The applica- |
-#                tion developer is now responsible for commiting (or   |
-#                for rolling back) the transaction [Bug #747525].      |
-#              - Added PG_TIMETZ to the mix [Patch #708013].           |
-#              - Pg_Money will now accept a string as a parameter.     |
-#              - PostgreSQL int2, int, int4 will now be cast into      |
-#                Python ints.  Int8 will be cast into a Python long.   |
-#                Float4, float8, and money types will be cast into     |
-#                a Python float.                                       |
-# 07MAR2003 bga - Correct problem with the PgNumeric.__radd__ method.  |
-#                [Bug #694358]                                         |
-#              - Correct problem with conversion of negitive integers  |
-#                (with a given scale and precision) to PgNumerics.     |
-#                [Bug #694358]                                         |
-#              - Work around a problem where the precision and scale   |
-#                of a query result can be different from the first re- |
-#                sult in the result set.                               |
-#                [Bug #697221]                                         |
-# 12JAN2003 bga        - Change the code so that the display length in the     |
-#                cursor.description attribute is always None instead   |
-#                of '-1'.                                              |
-#              - Fixed another problem with interval <-> DateTimeDelta |
-#                casting.                                              |
-# 23DEC2002 bga - Corrected a problem that caused the close of a portal        |
-#                (ie. PostgreSQL cursor) to fail.                      |
-# 13DEC2002 bga - Corrected a problem with interval <-> DateTimeDelta  |
-#                casting. [Bug #653044]                                |
-# 06DEC2002 bga - Corrected problem found by Adam Buraczewski in the   |
-#                __setupTransaction function.                          |
-#              - Allow both 'e' and 'E' to signify an exponet in the   |
-#                PgNumeric constructor.                                |
-# 04DEC2002 bga - Correct some problems that were missed in yesterday's        |
-#                fixes (Thanks, Adam, for the help with the problems)  |
-# 03DEC2002 bga - Fixed various problems with the constructor and the  |
-#                formatting routine.  These correct the problems re-   |
-#                ported by Adam Buraczewski.                           |
-# 01DEC2002 bga - Fixed problems with new __setupTransaction function: |
-#                1. Made it a method of Connection, not Cursor.        |
-#                2. inTransaction was only set if TransactionLevel was |
-#                   set.                                               |
-#              - Fixed instances where method name was incorrect:      |
-#                  Connection__gcCursor    -> _Connection__gcCursor    |
-#                  Connection__closeCursor -> _Connection__closeCursor |
-#              - Cleaned up code where there was unneeded references   |
-#                to conn in Connection class.                          |
-# 01DEC2002 gh  - Handle the new '__quote__' method for arrays, too.   |
-#              - Still handle '_quote' methods for backwards compati-  |
-#                bility.  This will will avoid complaints by users     |
-#                who have code depending on this.  Like me.            |
-# 28NOV2002 bga - Fixed changed PG_TIMESTAMP oid, added PG_TIMESTAMPTZ |
-#                and PG_REFCURSOR oids.  [Bug #845360]                 |
-#              - Reference cursors are now type-casted into cursor ob- |
-#                jects.                                                |
-# 27NOV2002 bga - Completed the emulation of a String object for the   |
-#                PgBytea and PgOther classes.  This corrects several   |
-#                problems with PgBytea concerning comparisons, using   |
-#                PgBytea types as keys in dictionaries, etc.           |
-# 10NOV2002 bga - Added the __hash__ function to the PgNumeric class.  |
-#                Cleaned up the code in PgNumeric class and made some  |
-#                small improvments to it.                              |
-# 02NOV2002 bga - Added the PgArray class.  This is a wrapper around a |
-#                Python list and is used for all PostgreSQL arrays.    |
-#                This change was made so that lists and tuples no      |
-#                longer have a special meaning in the Cursor.execute() |
-#                method.                                               |
-#              - Changed the quoting methods defined in the various    |
-#                classes defining PostgreSQL support types to __quote__|
-# 27OCT2002 gh  - Merged the Unicode patch. Closes #484468.             |
-#              - Convert ROWID to PgInt8 instead of PgInt4 (the origi- |
-#                nal behaviour led to overflow errors.)                |
-#              - Always set the displaysize field of                   |
-#                cursor.description to -1. PostgreSQL 7.3 doesn't      |
-#                provide this information any more and it's pretty     |
-#                useless nowadays that we've mostly left line printers |
-#                beyond us.                                            |
-# 26OCT2002 bga - Column access by name (attribute and dictionary) now |
-#                supports mixed-case column name.  Be aware that if    |
-#                you define mixed-case column names in the database,   |
-#                you have to use the mixed-case name to access the co- |
-#                lumn or it will not be found.  For column names that  |
-#                were not defined with mixed-case in the database, the |
-#                column access by name is case insensitive.            |
-# 02OCT2002 gh  - Only support mxDateTime 2.x and give useful error    |
-#                message if import fails.                              |
-#              - Cosmetic changes: use cmp builtin where appropriate.  |
-#              - Fixed typo where PgTypes.__str__ was spelled          |
-#                incorrectly. Compare to None using "is" operator.     |
-#              - Take into account that libpq.PgInt8Type might not be  |
-#                available.                                            |
-#              - Add support for the INTERVAL type.                    |
-# 08SEP2002 gh  Fixed various problems with the PgResultSet:           |
-#              - Column (attribute and dictionary) access is now case- |
-#                insensitive.                                          |
-#              - Added __contains__ method.                            |
-#              - Added default value parameter to get method.          |
-#              - Made setattr actually work.                           |
-# 11AUG2002 bga Fixed various problems with the PgNumeric type:                |
-#              - Added code to allow a float as an argument to the     |
-#                PgNumeric constructor.                                |
-#              - You can now change the precision/scale of a PgNumeric |
-#                by: a = PgNumeric(pgnumeric, new prec, new scale).    |
-#                This can be used to 'cast' a PgNumeric to the proper  |
-#                precision and scale before storing it in a field.     |
-#              - The arithmatic routines (__add__, __radd__, etc) now  |
-#                ensure that the arguments are properly coerced to the |
-#                correct types.                                        |
-#              - Added support for the augmented arithmatic operations |
-#                (__iadd__, etc).                                      |
-#              - The math routines would lose precision becuase the    |
-#                precision/scale were set to be the same as the first  |
-#                operand.  This is no longer the case all precision is |
-#                retained for the +, -, and * operations.              |
-# 03AUG2002 gh  - Fixed problem that occurs when a query on an OID     |
-#                field doesn't return any rows. [Bug #589370].         |
-# 29JUL2002 gh  - Applied patch #569203 and also added __pos__ and     |
-#                __abs__ special methods to PgNumeric.                 |
-# 15MAY2002 gh  - Got rid of redundant building and storing of the     |
-#                mapping of column names to column positions in the    |
-#                PgResultSet class. Now, rows of the same query are    |
-#                instances of a dynamically created class, which has   |
-#                this mapping as a class attribute instead of an at-   |
-#                tribute of the instance. This saves a lot of space,   |
-#                and also slightly increases performance of cursor     |
-#                fetches.                                              |
-# 21APR2002 gh  - Improved the array parsing, so that it now passes all        |
-#                the new mean testcases. Added support for parsing     |
-#                multidimensional arrays. Eventually, the array par-   |
-#                sing code should go as a support function into libpq. |
-#              - Replaced all typechecks with "is" operators instead   |
-#                of equals. Mark McEahern had a problem with using     |
-#                pyPgSQL in combination with a FixedPoint class where  |
-#                the reason was that the FixedPoint class was not com- |
-#                parable to None. The consensus on python-list was     |
-#                that None and all types are singletons, so they       |
-#                should be checked using "is", which is also faster,   |
-#                because it only checks for object identity.           |
-# --------- bga Remove prior comments to reduce the size of the flower |
-#              box.  See revision 1.22 for earlier comments.           |
-#--(H-)-----------------------------------------------------------------+
-"""
-    PgSQL - A PyDB-SIG 2.0 compliant module for PostgreSQL.
-
-    Copyright 2000 by Billy G. Allie <[email protected]>
-    See package documentation for further information on copyright.
-
-    Inline documentation is sparse.
-    See the Python DB-SIG 2.0 specification for usage information.
-
-    basic usage:
-
-       PgSQL.connect(connect_string) -> connection
-           connect_string = 'host:port:database:user:password:options:tty'
-           All parts are optional. You may also pass the information in as
-           keyword arguments with the following keywords: 'host', 'port',
-           'database', 'user', 'password', 'options', and 'tty'.  The port
-           may also be passed in as part of the host keyword parameter,
-           ie. host='localhost:5432'. Other optional parameters are
-           client_encoding and unicode_results. If unicode_results is true,
-           all strings from the backend are returned as Unicode strings.
-
-           client_encoding accepts the same parameters as the encode method
-           of Unicode strings. If you also want to set a policy for encoding
-           errors, set client_encoding to a tuple, like ("koi8-r", "replace")
-
-           Note that you still must make sure that the PostgreSQL client is
-           using the same encoding as set with the client_encoding parameter.
-           This is typically done by issuing a "SET CLIENT_ENCODING TO ..."
-           SQL statement immediately after creating the connection.
-
-       connection.cursor() -> cursor
-           Create a new cursor object.  A connection can support multiple
-           cursors at the same time.
-
-       connection.close()
-           Closes the connection now (instead of when __del__ is called).
-           The connection will be unusable from this point forward.
-           NOTE: Any uncommited transactions will be rolled back and any
-                 open cursors for this connection will be closed.
-
-       connection.commit()
-           Commit any pending transactions for this connection.
-
-           NOTE: This will reset any open cursors for this connection to their
-                 inital state.  Any PostgreSQL portals in use by cursors will
-                 be closed and any remaining query results will be discarded.
-
-       connection.rollback()
-           Rollback any pending transactions for this connection.
-
-           NOTE: This will reset any open cursors for this connection to their
-                 inital state.  Any PostgreSQL portals in use by cursors will
-                 be closed and any remaining query results will be discarded.
-
-       connection.binary(string) -> PgLargeObject
-           Create a new PostgreSQL large object.  If string is present, it is
-           written to the new large object.  The returned large object will
-           not be opened (i.e. it will be closed).
-       
-       connection.un_link(OID|PgLargeObject)
-           Un-links (removes) the PgLargeObject from the database.
-
-           NOTE: This is a PostgreSQL extension to the Connection object.
-                 It is not safe to un-link PgLargeObjects while in a trans-
-                 action (in versions prior to 7.1) since this action can not
-                 be rollbacked completely.  Therefore, an attempt to un-link
-                 while in a transaction (in versions prior to 7.1) will raise
-                 an exception.
-
-       connection.version
-           This instance of the PgVersion class contains information about
-           the version of the PostgreSQL backend to which the connection
-           object is connected to.
-
-           NOTE: This is a PgSQL extension to the Connection object.
-
-       cursor.execute(query[, param1[, param2, ..., paramN])
-           Execute a query, binding the parameters if they are passed. The
-           binding syntax is the same as the '%' operator except that only %s
-           [or %(name)s] should be used and the %s [or %(name)s] should not be
-           quoted.  Any necessary quoting will be performed by the execute
-           method.
-
-       cursor.execute(query[, sequence])
-           Execute a query, binding the contents of the sequence as parameters.
-           The binding syntax is the same as the '%' operator except that only
-           %s should be used and the %s should not be quoted.  Any necessary
-           quoting will be performed by the execute method.
-
-       cursor.execute(query[, dictionary])
-           Execute a query, binding the contents of the dictionary as para-
-           meters.  The binding syntax is the same as the '%' operator except
-           that only %s [or %(name)s] should be used and the %s [or %(name)s]
-           should not be quoted.  Any necessary quoting will be performed by
-           the execute method.
-
-       NOTE: In order to use a PostgreSQL portal (i.e. DECLARE ... CURSOR
-             FOR ...), the word SELECT must be the first word in the query,
-             and can only be be proceeded by spaces and tabs.  If this is not
-             the case, a cursor will be simulated by reading the entire result
-             set into memory and handing out the results as needed.
-
-       NOTE: PostgreSQL cursors are read-only.  SELECT ... FOR UPDATE queries
-             will not use PostgreSQL cursors, but will simulate a cursor by
-             reading the entire result set into memory and handing out the
-             results as needed.
-
-       NOTE: Setting the variable, PgSQL.noPostgresCursor, to 1 will cause
-             PgSQL to NOT use PostgreSQL cursor (DECLARE ... CURSOR FOR ...),
-             even if all the conditions for doing so are met.  PgSQL will
-             simulate a cursor by reading the entire result set into memory
-             and handing out the results as needed.
-
-       cursor.executemany(query, sequence_of_params)
-           Execute a query many times, once for each params in the sequence.
-
-       NOTE: The restriction on the use of PostgreSQL cursors described in
-             the cursor.execute() note also applies to cursor.executemany().
-             The params in the sequence of params can be a list, tuple or
-             dictionary.
-
-       cursor.fetchone() -> PgResultSet
-           Fetch the next row of the query result set as a single PgResultSet
-           containing the column data.  Returns None when no more rows are
-           available.  A PgResultSet is a sequence that can be indexed by
-           a column name in addition to an integer.
-
-       cursor.fetchmany([size]) -> [PgResultSet, ...]
-           Fetch the next set of rows from the query result, returning a
-           sequence of PgResultSets.  An empty sequence is returned when
-           no more rows are available.
-
-           The number of rows returned is determined by the size parameter.
-           If the size parameter is ommited, the value of cursor.arraysize
-           is used.  If size is given, cursor.arraysize is set to that value.
-
-       cursor.fetchall() -> [PgResultSet, ...]
-           Fetch all (remaining) rows from the query result, returning a
-           sequence of PgResultSets.  An empty sequence is returned when
-           no more rows are available.
-
-       cursor.description -> [(column info), ... ]
-           Returns a sequence of 8-item tuples.  Each tuple describes one
-           column of the result: (name, type code, display size, internal
-           size, precision, scale, null_ok, isArray).
-
-           NOTE: null_ok is not implemented.
-                 isArray is a PostgreSQL specific extension.
-
-       cursor.rowcount
-           The number of rows the last execute produced (for DQL statements)
-           or affected (for DML statement).
-
-       cursor.oidValue
-           The object ID of the inserted record, if the last SQL command
-           was an INSERT, otherwise it returns 0 (aka. InvalidOid)
-
-           NOTE: oidValue is a PostgreSQL specific extension.
-
-       cursor.close()
-           Closes the cursor now (instead of when __del__ is called).  The
-           cursor will be unusable from this point forward.
-
-       cursor.rewind()
-           Moves the cursor back to the beginning of the query result.
-           This is a PgSQL extension to the PyDB 2.0 API.
-
-       PgResultSet.description() -> [(column info), ... ]
-           Returns a sequence of 8-item tuples.  Each tuple describes one
-           column of the result: (name, type code, display size, internal
-           size, precision, scale, null_ok. isArray).
-
-           NOTE: null_ok is not implemented.
-                 isArray is a PostgreSQL specific extension.
-
-       PgResultSet.<column name> -> value
-           Column names are attributes to the PgResultSet.
-       
-       Note:   Setting the variable, PgSQL.fetchReturnsList = 1 will cause
-               the fetch*() methods to return a list instead of a PgResultSet.
-
-       PgSQL.version
-           This string object contains the version number of PgSQL.
-"""
-
-from types import *
-from sys import getrefcount, getdefaultencoding
-import sys
-import copy
-import string
-import re
-import new
-
-try:
-    import weakref
-    noWeakRef = 0
-except:
-    noWeakRef = 1
-
-try:
-    from mx import DateTime
-except ImportError:
-    raise ImportError, \
-       """You need to install mxDateTime
-       (http://www.egenix.com/files/python/eGenix-mx-Extensions.html)"""
-from pyPgSQL.libpq import *
-
-version = '$Revision: 1.2 $'
-
-apilevel = '2.0'
-threadsafety = 1
-paramstyle = 'pyformat'
-
-# Setting this variable to 1 will cause the fetch*() methods to return
-# a list instead of a PgResultSet
-
-fetchReturnsList = 0
-
-# Setting this variable to 1 will prevent the use of a PostgreSQL Cursor
-# (via the "DECLARE ... CURSOR FOR ..." syntax).  A cursor will be simulated
-# by reading all of the query result into memory and doling out the results
-# as needed.
-
-noPostgresCursor = 0
-
-re_DQL = re.compile('^[\s]*SELECT[\s]', re.I)
-re_DRT = re.compile('[\s]*DROP[\s]+TABLE[\s]', re.I)
-re_DRI = re.compile('[\s]*DROP[\s]+INDEX[\s]', re.I)
-re_4UP = re.compile('[\s]FOR[\s]+UPDATE', re.I)
-
-replace = string.replace
-
-#-----------------------------------------------------------------------+
-# Make the required Date/Time constructor visable in the PgSQL module. |
-#-----------------------------------------------------------------------+
-
-Date = DateTime.Date
-Time = DateTime.Time
-Timestamp = DateTime.Timestamp
-DateFromTicks = DateTime.DateFromTicks
-TimeFromTicks = DateTime.TimeFromTicks
-TimestampFromTicks = DateTime.TimestampFromTicks
-
-#-----------------------------------------------+
-# The DateTimeDelta type for PgInterval support |
-#-----------------------------------------------+
-
-DateTimeDelta = DateTime.DateTimeDelta
-
-#-------------------------------+
-# Also the DateTime types      |
-#-------------------------------+
-
-DateTimeType = DateTime.DateTimeType
-DateTimeDeltaType = DateTime.DateTimeDeltaType
-DateTimeDelta = DateTime.DateTimeDelta
-
-#-----------------------------------------------------------------------+
-# Name:                DBAPITypeObject                                         |
-#                                                                      |
-# Description:  The DBAPITypeObject class allows implementing the re-  |
-#              quired DP-API 2.0 type objects even if their are multi- |
-#              ple database types for the DP-API 2.0 types.            |
-#                                                                      |
-# Note:                This object is taken from the Python DP-API 2.0 imple-  |
-#              mentation hints.                                        |
-#-----------------------------------------------------------------------+
-
-class DBAPITypeObject:
-    def __init__(self, name, *values):
-       self.name = name
-       self.values = values
-
-    def __repr__(self):
-       return self.name
-
-    def __cmp__(self, other):
-       if other in self.values:
-           return 0
-       elif other < self.values:
-           return 1
-       return -1
-
-# Define the object types required by the DB-API 2.0 specification.
-
-BINARY  = DBAPITypeObject('BINARY', PG_OID, PG_BLOB, PG_BYTEA)
-
-DATETIME = DBAPITypeObject('DATETIME', PG_DATE, PG_TIME, PG_TIMETZ,
-                                      PG_TIMESTAMP, PG_TIMESTAMPTZ,
-                                      PG_ABSTIME, PG_RELTIME,
-                                       PG_INTERVAL, PG_TINTERVAL)
-
-NUMBER  = DBAPITypeObject('NUMBER', PG_INT8, PG_INT2, PG_INT4, PG_FLOAT4,
-                                    PG_FLOAT8, PG_MONEY, PG_NUMERIC)
-
-ROWID   = DBAPITypeObject('ROWID', PG_OID, PG_ROWID, PG_CID, PG_TID, PG_XID)
-
-STRING  = DBAPITypeObject('STRING', PG_CHAR, PG_BPCHAR, PG_TEXT, PG_VARCHAR,
-                                    PG_NAME)
-
-# BOOLEAN is the PostgreSQL boolean type.
-
-BOOLEAN  = DBAPITypeObject('BOOLEAN', PG_BOOL)
-
-# OTHER is for PostgreSQL types that don't fit in the standard Objects.
-
-OTHER   = DBAPITypeObject('OTHER', PG_POINT, PG_LSEG, PG_PATH, PG_BOX,
-                                   PG_POLYGON, PG_LINE, PG_CIDR, PG_CIRCLE,
-                                   PG_INET, PG_MACADDR, PG_ACLITEM,
-                                    PG_REFCURSOR)
-
-#-----------------------------------------------------------------------+
-# Name:                PgTypes                                                 |
-#                                                                      |
-# Description: PgTypes is an object wrapper for the type OID's used by |
-#              PostgreSQL.  It is used to display a meaningful text    |
-#              description of the type while still allowing it to be   |
-#              compared as a numeric value.                            |
-#-----------------------------------------------------------------------+
-
-class PgTypes:
-    def __init__(self, value):
-       self.value = value
-
-    def __coerce__(self, other):
-       if type(other) in [IntType, LongType, FloatType]:
-           return (self.value, int(other))
-       return None
-
-    def __cmp__(self, other):
-       return cmp(self.value, other)
-
-    def __repr__(self):
-       return repr(self.value)
-
-    def __str__(self):
-       return PQftypeName(self.value)
-
-    def __int__(self):
-       return int(self.value)
-
-    def __long__(self):
-       return long(self.value)
-
-    def __float__(self):
-       return float(self.value)
-
-    def __complex__(self):
-       return complex(self.value)
-
-#-----------------------------------------------------------------------+
-# Name:                TypeCache                                               |
-#                                                                      |
-# Description: TypeCache is an object that defines methods to:         |
-#              1.  Cast PostgreSQL result strings into the appropiate  |
-#                  Python type or object [typecast()].                 |
-#              2.  Retrieve addition information about a type from the |
-#                  PostgreSQL system catalogs [getTypeInfo()].  This   |
-#                  type information is maintained in a local cache so  |
-#                  that subsequent request for the same information do |
-#                  not require a database query to fulfill it.         |
-#-----------------------------------------------------------------------+
-
-class TypeCache:
-    """Type cache -- used to cache postgreSQL data type information."""
-
-    def __init__(self, conn):
-       if noWeakRef:
-           self.__conn = conn
-       else:
-           self.__conn = weakref.proxy(conn, self.__callback)
-       self.__type_cache = {}
-       self.__lo_cache = {}
-    
-    def __callback(self, o):
-       self.__conn = None
-
-    def interval2DateTimeDelta(self, s):
-       """Parses PostgreSQL INTERVALs.
-       The expected format is [[[-]YY years] [-]DD days] [-]HH:MM:SS.ss"""
-       parser = DateTime.Parser.DateTimeDeltaFromString
-
-       ydh = s.split()
-       ago = 1
-
-       result = DateTimeDelta(0) 
-
-       # Convert any years using 365.2425 days per year, which is PostgreSQL's
-       # assumption about the number of days in a year.
-        if len(ydh) > 1:
-            if ydh[1].lower().startswith('year'):
-                result += parser('%s days' % ((int(ydh[0]) * 365.2425),))
-                ydh = ydh[2:]
-       
-       # Converts any days and adds it to the years (as an interval)
-        if len(ydh) > 1:
-            if ydh[1].lower().startswith('day'):
-                result += parser('%s days' % (ydh[0],))
-                ydh = ydh[2:]
-
-       # Adds in the hours, minutes, seconds (as an interval)
-        if len(ydh) > 0:
-            result += parser(ydh[0])
-
-       return result
-
-    def parseArray(self, s):
-       """Parse a PostgreSQL array strings representation.
-       This parses a PostgreSQL array and return a list of the array
-       elements as strings.
-       """
-       class LeaveLoopException(Exception): pass
-
-       # Get rid of the escaping in the array string
-       def convertEscapes(s):
-           # If we're called with a list in a multi-dimensional
-           # array, simply return the list. We only convert the
-           # elements of the multi-dimensional array.
-           if type(s) is ListType:
-               return s
-
-           schars = []
-           escape = 0
-           octdigits = []
-
-           for char in s:
-               if char == '\\':
-                   escape += 1
-                   if escape == 2:
-                       schars.append(char)
-                       escape = 0
-               else:
-                   if escape:
-                       if char in string.digits:
-                           octdigits.append(char)
-                       else:
-                           if octdigits != []:
-                               curchar = chr(int(octdigits[0]) * 64) + \
-                                         chr(int(octdigits[1]) * 8) + \
-                                         chr(int(octdigits[2]))
-                               schars.append(curchar)
-                               octdigits = []
-                           schars.append(char)
-                   else:
-                       schars.append(char)
-                   escape = 0
-           return "".join(schars)
-
-       lst = PgArray()
-       s = s[1:-1] # drop '{' and '}' at start/end
-
-       # If the array is empty, return immediately
-       if len(s) == 0:
-           return lst
-
-       pos = 0
-       try:
-           while 1:
-               if s[pos] == '"':
-                   # A quoted element, find the end-quote, which is the next
-                   # quote char that is not escaped.
-                   end_quote_pos = pos + 1
-                   escape = 0
-                   while 1:
-                       if s[end_quote_pos] == '\\':
-                           escape = not escape
-                       elif s[end_quote_pos] == '"':
-                           if not escape:
-                               break
-                           escape = 0
-                       else:
-                           escape = 0
-                       end_quote_pos += 1
-                   lst.append(convertEscapes(s[pos + 1:end_quote_pos]))
-                   
-                   # Skip quote char and next comma
-                   pos = end_quote_pos + 2
-
-                   # If end-of-string. leave loop.
-                   if pos >= len(s):
-                       break
-               else:
-                   # This array element is not quoted, so it ends either at
-                   # the next comma that isn't escaped, or at the end of the
-                   # string, or, if it contains a subarray, at the position
-                   # of the corresponding curly brace.
-                   if s[pos] != '{':
-                       next_comma_pos = pos + 1
-                       escape = 0
-                       while 1:
-                           if next_comma_pos >= len(s):
-                               # This is the last array element.
-                               lst.append(convertEscapes(s[pos:]))
-                               raise LeaveLoopException
-
-                           if s[next_comma_pos] == '\\':
-                               escape = not escape
-                           elif s[next_comma_pos] == ',':
-                               if not escape:
-                                   break
-                               escape = 0
-                           else:
-                               escape = 0
-                           next_comma_pos += 1
-
-                       curelem = s[pos:next_comma_pos]
-                       if curelem.startswith("{"):
-                           lst.append(self.parseArray(curelem[1:-1]))
-                       else:
-                           lst.append(convertEscapes(curelem))
-                       pos = next_comma_pos + 1
-                       if s[pos] == ',':
-                           pos += 1
-                   else:
-                       # The current character is '{', which means we've
-                       # found a sub-array:
-                       # We find the end of the sub-array, then feed this
-                       # string into parseArray again.
-                       escape = 0
-                       open_braces = 1
-                       closing_brace_pos = pos + 1
-                       in_quotes = 0
-                       while 1:
-                           if s[closing_brace_pos] == '\\':
-                               escape = not escape
-                           elif s[closing_brace_pos] == '{':
-                               if (not escape) and (not in_quotes):
-                                   open_braces += 1
-                               escape = 0
-                           elif s[closing_brace_pos] == '}':
-                               if (not escape) and (not in_quotes):
-                                   open_braces -= 1
-                                   if open_braces == 0:
-                                       break
-                               escape = 0
-                           elif s[closing_brace_pos] == '"':
-                               if not escape:
-                                   in_quotes = not in_quotes
-                               escape = 0
-                           else:
-                               escape = 0
-                           closing_brace_pos += 1
-
-                       curelem = s[pos:closing_brace_pos + 1]
-                       lst.append(self.parseArray(curelem))
-                       pos = closing_brace_pos + 1
-                       if pos >= len(s):
-                           break
-                       if s[pos] == ',':
-                           pos += 1
-
-       except LeaveLoopException:
-           pass
-
-       #lst = map(convertEscapes, lst)
-       return lst
-
-    def typecast(self, colinfo, value):
-       """
-       typecast(rowinfo, value)
-           Convert certain postgreSQL data types into the appropiate python
-           object."""
-
-       if value is None:
-           return value
-
-       _fn, _ft, _ds, _is, _p, _s, _nu, _ia = colinfo
-
-       _ftv = _ft.value
-       
-       if _ia:
-           # Convert string representation of the array into PgArray object.
-           _list = self.parseArray(value)
-           return self.handleArray(colinfo, _list)
-
-       if _ftv == PG_INT2:
-           if type(value) is PgInt2Type:
-               return value
-           else:
-               return int(value)
-       elif _ftv == PG_INT4:
-           if type(value) is IntType:
-               return value
-           else:
-               return int(value)
-       elif _ftv == PG_INT8 or _ftv == ROWID:
-           if type(PgInt8) is ClassType:
-               if isinstance(value, PgInt8):
-                   return value
-           else:
-               if type(value) is PgInt8Type:
-                   return value
-           return long(value)
-       elif _ftv == PG_NUMERIC:
-           if isinstance(value, PgNumeric):
-               return value
-           else:
-               try:
-                   return PgNumeric(value, _p, _s)
-               except OverflowError:
-                   # If we reached this point, then the precision and scale
-                   # of the current field does not match the precision and
-                   # scale of the first record in the result set (there are
-                   # a few reasons why this can happen).  Let PgNumeric
-                   # figure out a precision and scale from the value.
-                   return PgNumeric(value)
-       elif _ftv == PG_MONEY:
-           if isinstance(value, PgMoney):
-               return value
-           else:
-               return PgMoney(value).value
-       elif _ftv == DATETIME:
-           if type(value) in [DateTimeType, DateTimeDeltaType]:
-               return value
-           else:
-               if _ftv == PG_INTERVAL:
-                   return value #self.interval2DateTimeDelta(value)
-               else:
-                   return value #DateTime.ISO.ParseAny(value)
-       elif _ftv == BINARY:
-           if isinstance(value, PgBytea) or type(value) is PgLargeObjectType:
-               return value
-           elif type(value) is IntType:
-               return PgLargeObject(self.conn, value)
-           else:
-               return PgBytea(value)
-        elif _ftv == PG_REFCURSOR:
-            return self.__conn.cursor(value, isRefCursor=PG_True)
-       elif _ftv == OTHER:
-           if isinstance(value, PgOther):
-               return value
-           else:
-               return value
-       elif self.__conn.unicode_results \
-         and _ftv in (PG_CHAR, PG_BPCHAR, PG_TEXT, PG_VARCHAR, PG_NAME):
-           return unicode(value, *self.__conn.client_encoding)
-       # Other typecasting is not needed.  It will be once support for
-       # the other built-in types (ie. box, line, inet, cidr, etc) are added.
-       
-       return value
-
-    def handleArray(self, colinfo, lst):
-       # If the list is empty, just return the empty list.
-
-       if len(lst) == 0:
-           return lst
-
-       _fn, _ft, _ds, _is, _p, _s, _nu, _ia = colinfo
-
-       _ftv = _ft.value
-
-       for _i in range(len(lst)):
-           if isinstance(lst[_i], PgArray):
-               lst[_i] = self.handleArray(colinfo, lst[_i])
-           elif _ftv == PG_INT4 or _ftv == ROWID:
-               lst[_i] = int(lst[_i])
-           elif _ftv == PG_INT8:
-               lst[_i] = PgInt8(lst[_i])
-           elif _ftv == PG_NUMERIC:
-               try:
-                    lst[_i] = PgNumeric(lst[_i], _p, _s)
-               except OverflowError:
-                   # If we reached this point, then the precision and scale
-                   # of the current field does not match the precision and
-                   # scale of the first record in the result set (there are
-                   # a few reasons why this can happen).  Let PgNumeric
-                   # figure out a precision and scale from the value.
-                    lst[_i] = PgNumeric(lst[_i])
-           elif _ftv == PG_INT2:
-               lst[_i] = PgInt2(lst[_i])
-           elif _ftv == DATETIME:
-               lst[_i] = DateTime.ISO.ParseAny(lst[_i])
-           elif _ftv == PG_MONEY:
-               if lst[_i][0] == '(':
-                   lst[_i] = PgMoney(-float(replace(lst[_i][2:-1], ',', '')))
-               elif lst[_i][0] == '-':
-                   lst[_i] = PgMoney(-float(replace(lst[_i][2:], ',', '')))
-               else:
-                   lst[_i] = PgMoney(float(replace(lst[_i][1:], ',', '')))
-           elif _ftv == BINARY:
-               if _ftv == PG_BYTEA:
-                   # There is no need to un-escape lst[_i], it's already been
-                   # done when the PostgreSQL array was converted to a list
-                   # via parseArray().
-                   lst[_i] = PgBytea(lst[_i])
-               else:
-                   lst[_i] = PgLargeObject(self.conn, int(lst[_i]))
-                   
-       return lst
-
-    def getTypeInfo(self, pgtype):
-       try:
-           return self.__type_cache[pgtype.value]
-       except KeyError:
-           _nl = len(self.__conn.notices)
-           _res = self.__conn.conn.query("SELECT typname, -1 , typelem "
-                                         "FROM pg_type "
-                                         "WHERE oid = %s" % pgtype.value)
-
-           if len(self.__conn.notices) != _nl:
-               raise Warning, self.__conn.notices.pop()
-
-           _n = _res.getvalue(0, 0)
-           _p = _res.getvalue(0, 1)
-           _b = _res.getvalue(0, 2)
-           if _n[0] == '_':
-               _n = _n[1:]
-               _i = 1
-           else:
-               _i = 0
-
-           self.__type_cache[pgtype.value] = (_n, _p, _i, PgTypes(_b))
-       
-       return self.__type_cache[pgtype.value]
-
-#-----------------------------------------------------------------------+
-# Name:                PgOther                                                 |
-#                                                                      |
-# Description: A Python wrapper class for the PostgreSQL types that do |
-#              not (yet) have an implementation in python.  The number |
-#              of types in this category will shrink as more wrappers  |
-#              are implemented.                                        |
-#                                                                      |
-# Note:                A Python String is used to store the PostgreSQL type in |
-#              class.                                                  |
-#-----------------------------------------------------------------------+
-
-class PgOther:
-    def __init__(self, value):
-       if type(value) is not StringType:
-           raise TypeError, "argument must be a string."
-
-       self.value = value
-
-       if hasattr(value, '__methods__'):
-           for i in self.value.__methods__:
-               exec 'self.%s = self.value.%s' % (i, i)
-
-    # This definition of __coerce__ will cause Python to always call the
-    # (existing) arithmatic operators for this class.  We can the perform the
-    # appropiate operation on the base type, letting it decide what to do.
-    def __coerce__(self, other):
-           return (self, other)
-
-    def __getitem__(self, index):
-       if type(index) is SliceType:
-           if index.step is None:
-               return PgOther(self.value[index.start:index.stop])
-           else:
-               return PgOther(self.value[index.start:index.stop:index.step])
-
-       return self.value[index];
-    
-    def __setitem__(self, index, item):
-        raise TypeError, "object doesn't support slice assignment"
-
-    def __delitem__(self, index):
-        raise TypeError, "object doesn't support slice deletion"
-    
-    def __contains__(self, item):
-       return (item in self.value)
-
-    if sys.version_info < (2, 0):
-       # They won't be defined if version is at least 2.0 final
-       def __getslice__(self, i, j):
-           return PgOther(self.value[max(0, i):max(0, j)])
-
-       def __setslice__(self, i, j, seq):
-            raise TypeError, "object doesn't support slice assignment"
-        
-       def __delslice__(self, i, j):
-            raise TypeError, "object doesn't support slice deletion"
-
-    # NOTE: A string is being concatenated to a PgOther, so the result type
-    #       is a PgOther
-    def __add__(self, other):
-       return PgOther((self.value + other))
-
-    # NOTE: A PgOther is being concatenated to a string, so the result type
-    #       is a string.
-    def __radd__(self, other):
-       return (other + self.value)
-
-    def __mul__(self, other):
-       return PgOther((self.value * other))
-
-    def __rmul__(self, other):
-       return PgOther((self.value * other))
-
-    def __repr__(self):
-       return repr(self.value)
-
-    def __str__(self):
-       return str(self.value)
-
-    def __hash__(self):
-        return hash(self.value)
-
-    def __cmp__(self, other):
-        return cmp(self.value, other)
-
-    def __rcmp__(self, other):
-        return cmp(other, self.value)
-
-    def __lt__(self, other):
-        return self.value < other
-
-    def __le__(self, other):
-        return self.value <= other
-
-    def __eq__(self, other):
-        return self.value == other
-
-    def __ne__(self, other):
-        return self.value != other
-
-    def __gt__(self, other):
-        return self.value > other
-
-    def __ge__(self, other):
-        return self.value >= other
-
-    # NOTE: A PgOther object will use the PgQuoteString() function in libpq.
-    def _quote(self, forArray=0):
-       if self.value:
-           return PgQuoteString(self.value, forArray)
-       return 'NULL'
-
-#-----------------------------------------------------------------------+
-# Name:                PgArray                                                 |
-#                                                                      |
-# Description: A Python wrapper class for PostgreSQL arrays.           |
-#              It is used so that the list type can be used as an arg- |
-#              ument to Connection.execute() without being treated as  |
-#              a PostgreSQL array.                                     |
-#-----------------------------------------------------------------------+
-
-class PgArray:
-    def __init__(self, value=None):
-       if value is None:
-           self.value = []
-           return
-
-       if type(value) is not ListType and not isinstance(value, PgArray):
-           raise TypeError, "argument must be a list or a PgArray."
-
-       # We have to insure that nested mutable sequences (list and PgArray)
-       # get copied.
-       for i in range(len(value)):
-           if type(value[i]) is ListType or isinstance(value[i], PgArray):
-               value[i] = PgArray(value[i][:])
-
-       self.value = value
-
-    # Define the methods used
-    def append(self, item):
-       if type(item) is ListType:
-           item = PgArray(item)
-       self.value.append(item)
-
-    def count(self, item):
-       return self.value.count(item)
-
-    def extend(self, item):
-       if type(item) is ListType:
-           item = PgArray(item)
-       self.value.extend(item)
-
-    def index(self, item):
-       return self.value.index(item)
-
-    def insert(self, key, item):
-       if type(item) is ListType:
-           item = PgArray(item)
-       self.value.insert(key, item)
-
-    def pop(self, key=-1):
-       return self.value.pop(key)
-
-    def remove(self, item):
-       self.value.remove(item)
-
-    def reverse(self):
-       self.value.reverse()
-
-    def sort(self, compfunc=None):
-       if compfunc is None:
-           self.value.sort()
-       else:
-           self.value.sort(compfunc)
-
-    def __cmp__(self, other):
-       if not isinstance(other, PgArray):
-           return cmp(id(self), id(other))
-
-       # PgArray objects are considered equal if:
-       #   1.  The lengh of the PgArray objects are equal and
-       #   2.  Each item[k] in the PgArray objects are equal.
-
-       res = cmp(len(self), len(other))
-       if res != 0:
-           return res
-
-       for i in range(len(self.value)):
-           res = cmp(self.value[i], other.value[i])
-           if res != 0:
-               return res
-
-       return 0
-
-    def __len__(self):
-       return len(self.value)
-
-    def __getitem__(self, index):
-       if type(index) is SliceType:
-           if index.step is None:
-               return PgArray(self.value[index.start:index.stop])
-           else:
-               return PgArray(self.value[index.start:index.stop:index.step])
-
-       return self.value[index];
-    
-    def __setitem__(self, index, item):
-       if type(item) is ListType:
-           item = PgArray(item)
-
-       if type(index) is SliceType:
-           if index.step is None:
-               self.value[index.start:index.stop] = item
-           else:
-               self.value[index.start:index.stop:index.step] = item
-       else:
-           self.value[index] = item
-
-    def __delitem__(self, index):
-       if type(index) is SliceType:
-           if index.step is None:
-               del self.value[index.start:index.stop]
-           else:
-               del self.value[index.start:index.stop:index.step]
-       else:
-           del self.value[index];
-    
-    def __contains__(self, item):
-       return (item in self.value)
-
-    if sys.version_info < (2, 0):
-       # They won't be defined if version is at least 2.0 final
-       def __getslice__(self, i, j):
-           return PgArray(self.value[max(0, i):max(0, j)])
-
-       def __setslice__(self, i, j, seq):
-           if type(seq) is ListType:
-               seq = PgArray(seq)
-           self.value[max(0, i):max(0, j)] = seq.value
-
-       def __delslice__(self, i, j):
-           del self.value[max(0, i):max(0, j)]
-
-    def __add__(self, other):
-       return PgArray((self.value + other))
-
-    def __radd__(self, other):
-       return PgArray(other + self.value)
-
-    def __iadd__(self, other):
-       value = value + other
-       return self
-
-    def __mul__(self, other):
-       return PgArray((self.value * other))
-
-    def __rmul__(self, other):
-       return PgArray((self.value * other))
-
-    def __imul__(self, other):
-       value = value * other
-       return self
-
-    def __repr__(self):
-       return repr(self.value)
-    
-    def __str__(self):
-       return str(self.value)
-
-    # NOTE: A PgArray object will use the _handleArray() function to quote
-    #      itself.
-    def _quote(self, forArray=0):
-       if self.value:
-           return _handleArray(self.value)
-       return 'NULL'
-
-#-----------------------------------------------------------------------+
-# Name:                PgBytea                                                 |
-#                                                                      |
-# Description: A Python wrapper class for the PostgreSQL BYTEA type.   |
-#                                                                      |
-# Note:                A Python String is used to store the PostgreSQL type in |
-#              class.                                                  |
-#-----------------------------------------------------------------------+
-
-class PgBytea:
-    def __init__(self, value):
-       if type(value) is not StringType:
-           raise TypeError, "argument must be a string."
-
-       self.value = value
-
-       if hasattr(value, '__methods__'):
-           for i in self.value.__methods__:
-               exec 'self.%s = self.value.%s' % (i, i)
-
-    # This definition of __coerce__ will cause Python to always call the
-    # (existing) arithmatic operators for this class.  We can the perform the
-    # appropiate operation on the base type, letting it decide what to do.
-    def __coerce__(self, other):
-           return (self, other)
-
-    def __getitem__(self, index):
-       if type(index) is SliceType:
-           if index.step is None:
-               return PgBytea(self.value[index.start:index.stop])
-           else:
-               return PgBytea(self.value[index.start:index.stop:index.step])
-
-       return self.value[index];
-    
-    def __setitem__(self, index, item):
-        raise TypeError, "object doesn't support slice assignment"
-
-    def __delitem__(self, index):
-        raise TypeError, "object doesn't support slice deletion"
-    
-    def __contains__(self, item):
-       return (item in self.value)
-
-    if sys.version_info < (2, 0):
-       # They won't be defined if version is at least 2.0 final
-       def __getslice__(self, i, j):
-           return PgBytea(self.value[max(0, i):max(0, j)])
-
-       def __setslice__(self, i, j, seq):
-            raise TypeError, "object doesn't support slice assignment"
-        
-       def __delslice__(self, i, j):
-            raise TypeError, "object doesn't support slice deletion"
-
-    def __add__(self, other):
-       return PgBytea((self.value + other))
-
-    def __radd__(self, other):
-       return PgBytea(other + self.value)
-
-    def __mul__(self, other):
-       return PgBytea((self.value * other))
-
-    def __rmul__(self, other):
-       return PgBytea((self.value * other))
-
-    def __repr__(self):
-       return repr(self.value)
-    
-    def __str__(self):
-       return str(self.value)
-
-    def __hash__(self):
-        return hash(self.value)
-
-    def __cmp__(self, other):
-        return cmp(self.value, other)
-
-    def __rcmp__(self, other):
-        return cmp(other, self.value)
-
-    def __lt__(self, other):
-        return self.value < other
-
-    def __le__(self, other):
-        return self.value <= other
-
-    def __eq__(self, other):
-        return self.value == other
-
-    def __ne__(self, other):
-        return self.value != other
-
-    def __gt__(self, other):
-        return self.value > other
-
-    def __ge__(self, other):
-        return self.value >= other
-    
-    # NOTE: A PgBytea object will use the PgQuoteBytea() function in libpq
-    def _quote(self, forArray=0):
-       if self.value:
-           return PgQuoteBytea(self.value, forArray)
-       return 'NULL'
-
-#-----------------------------------------------------------------------+
-# Name:                PgNumeric                                               |
-#                                                                      |
-# Description: A Python wrapper class for the PostgreSQL numeric type. |
-#              It implements addition, subtraction, mulitplcation, and |
-#              division of scaled, fixed precision numbers.            |
-#                                                                      |
-# Note:                The PgNumeric class uses a Python Long type to store    |
-#              the PostgreSQL numeric type.                            |
-#-----------------------------------------------------------------------+
-    
-class PgNumeric:
-    def __init__(self, value, prec=None, scale=None):
-       if type(value) in [IntType, LongType] or value is None:
-           if prec is None or scale is None:
-               raise TypeError, \
-                     "you must supply precision and scale when value is a " \
-                     "integer, long, or None"
-           if value is None:
-               self.__v = value
-           else:
-               self.__v = long(value)
-               # Check to see if the value is too large for the given
-               # precision/scale
-               _v = str(abs(value))
-               if _v[-1:] == 'L':
-                   _v = _v[:-1]
-               if len(_v) > prec:
-                   raise OverflowError, "value too large for PgNumeric"
-
-           self.__p = prec
-           self.__s = scale
-        elif type(value) in (FloatType, StringType):
-           # Get the value to convert as a string.
-           # The expected input is in the form of [+|-][d]*[.[d]*][e[d]+]
-
-           # First get the value as a (trimmed) string
-           if type(value) is FloatType:
-               _v = str(value)
-           else:
-               _v = value.split()
-               if len(_v) == 0 or len(_v) > 1:
-                   raise ValueError, \
-                         "invalid literal for PgNumeric: %s" % value
-               _v = _v[0]
-           
-           # Save the sign character (if any) and remove from the string
-           _sign = '+'
-           if _v[0] in ('-', '+'):
-               _sign = _v[0]
-               _v = _v[1:]
-
-           # Split the remaining string into int part, frac part and exponet
-            _d = _v.rfind('.')
-            _e = _v.rfind('e')
-
-           # Ensure that _e and _v contains a sane value
-           if _e < 0:
-               _e = _v.rfind('E')
-               if _e < 0:
-                   _e = len(_v)
-
-           if _d < 0:
-               _d = _e
-
-           _ip = _v[:_d]
-           _fp = _v[_d+1:_e]
-           _xp = _v[_e+1:]
-
-           # Check the validity of the input
-           if len(_ip) == 0 and len(_fp) == 0:
-               raise ValueError, \
-                     "invalid literal for PgNumeric: %s" % value
-
-            if len(_xp) > 0:
-               try:
-                   _exp = int(_xp)
-               except:
-                   raise ValueError, \
-                         "invalid literal for PgNumeric: %s" % value
-           else:
-               _exp = 0
-
-            if _exp > 999:
-                raise OverflowError, "value too large for PgNumeric"
-
-            if _exp < -999:
-                raise OverflowError, "value too small for PgNumeric"
-
-           # Create the string that will become the base (long) object
-           _v = _ip + _fp
-
-           _sc = len(_fp)
-            if _exp > 0:
-               if _exp > _sc:
-                   _v = _v + ("0" * (_exp - _sc))
-                   _sc = 0
-               else:
-                   _sc = _sc - _exp
-            else:
-                _sc = _sc - _exp
-
-            try:
-                self.__v = long(_sign + _v)
-            except:
-                raise ValueError, \
-                      "invalid literal for PgNumeric: %s" % value
-
-            self.__p = len(_v)
-            if self.__p < _sc:
-                self.__p = _sc
-            self.__s = _sc
-
-           # Now adjust for the inputted scale (if any)
-           if scale is None:
-               pass
-           else:
-               _adj = scale - self.__s
-               if _adj > 0:
-                   self.__v = self.__v * (10L ** (scale - self.__s))
-               elif _adj < 0:
-                   self.__v = self._round(self.__v, -_adj)
-               
-               self.__p = self.__p + _adj
-               self.__s = scale
-           
-           # Apply the inputted precision (if any)
-           if prec is None:
-               pass
-           else:
-               if prec > 1000:
-                   raise ValueError, "precision too large for PgNumeric"
-               elif self.__p > prec:
-                   raise OverflowError, "value too large for PgNumeric"
-               else:
-                   self.__p = prec
-        elif isinstance(value, PgNumeric):
-            # This is used to "cast" a PgNumeric to the specified precision
-            # and scale.  It can also make a copy of a PgNumeric.
-            self.__v = value.__v
-            if scale:
-                self.__s = scale
-                _ds = scale - value.__s
-            else:
-                self.__s = value.__s
-                _ds = 0
-            if prec:
-                self.__p = prec
-            else:
-                self.__p = value.__p
-            # Now we adjust the value to reflect the new scaling factor.
-            if _ds > 0:
-                if _ds == 1:
-                    self.__v = self.__v * 10
-                else:
-                    self.__v = self.__v * (10L ** _ds)
-            elif _ds < 0:
-                self.__v = self._round(self.__v, -_ds)
-            if self.__v > (10L ** self.__p):
-                raise OverflowError, "result exceeds precision of %d" % self.__p
-        else:
-           raise TypeError, "value can not be converted to a PgNumeric."
-
-       if self.__s > self.__p:
-           raise ValueError, \
-                 "scale of %d exceeds precision of %d" % (self.__s, self.__p)
-
-       # The value (10L ** self.__s) is used a lot.  Save it as a constant
-       # to save a (small) bit of time.
-
-       self.__sf = 10L ** self.__s
-
-    def __fmtNumeric(self, value=None):
-       if value is None:
-           _v = self.__v
-       else:
-           _v = value
-
-       # Check for a negative value and adjust if necessary
-       if _v < 0:
-           _sign = '-'
-           _v = -_v
-       else:
-           _sign = ''
-       _v = str(_v)
-
-       # Check to see if the string representation of the python long has
-       # a trailing 'L', if so, remove it.  Python 1.5 has the trailing 'L',
-       # Python 1.6 does not.
-       if _v[-1:] == 'L':
-           _v = _v[:-1]
-
-       # Check to see if the numeric is less than one and fix string if so.
-       if len(_v) <= self.__s:
-           _v = ("0" * (self.__s - len(_v) + 1)) + _v
-
-       if self.__s:
-           _s = "%s%s.%s" % (_sign, _v[:-(self.__s)], _v[-(self.__s):])
-       else:
-           _s = "%s%s" % (_sign, _v)
-       return _s
-
-    def __repr__(self):
-       return "<PgNumeric instance - precision: %d scale: %d value: %s>" % \
-              (self.__p, self.__s, self.__fmtNumeric())
-
-    def __str__(self):
-       return self.__fmtNumeric()
-
-    def getScale(self):
-       return self.__s
-
-    def getPrecision(self):
-       return self.__p
-
-    def __coerce__(self, other):
-        if isinstance(other, PgNumeric):
-            return self, other
-        elif type(other) in [IntType, LongType]:
-            _s = str(other)
-           if _s[-1:] == 'L':
-               _s = _s[:-1] # Work around v1.5/1.6 differences
-            return (self, PgNumeric(_s))
-        elif type(other) == FloatType:
-            return (self, PgNumeric(other))
-        return None
-
-    def _round(self, value, drop):
-       if drop == 1:
-           return ((value + 5L) / 10L)
-        elif drop > 1:
-           return (((value / (10L ** (drop - 1))) + 5L) / 10L)
-
-       return value
-
-    def __add__(self, other):
-        _c = self.__coerce__(other)
-        if _c is None:
-            return None
-        self, other = _c
-       if self.__s < other.__s:
-            _s = self.__v * (other.__sf / self.__sf)
-            _o = other.__v
-       elif self.__s > other.__s:
-            _s = self.__v
-            _o = other.__v * (self.__sf / other.__sf)
-        else:
-            _s = self.__v
-            _o = other.__v
-
-       mp = max(self.__p - self.__s, other.__p - other.__s)
-       ms = max(self.__s, other.__s)
-       v = _s + _o
-       # Check to see if the addition caused an increase in the precision
-       # due to a carry. If so, compensate for it.
-       if (v / (10L ** (mp + ms))) > 0:
-           mp = mp + 1
-
-       return PgNumeric((_s + _o), (mp + ms), ms)
-
-    def __radd__(self, other):
-       return self.__add__(other)
-
-    def __iadd__(self, other):
-        _r = self.__add__(other)
-        if _r is None:
-            return None
-        self.__v  = _r.__v
-        self.__p  = _r.__p
-        self.__s  = _r.__s
-        self.__sf = _r.__sf
-       return self
-        
-    def __sub__(self, other):
-        _c = self.__coerce__(other)
-        if _c is None:
-            return None
-        self, other = _c
-       if self.__s < other.__s:
-            _s = self.__v * (other.__sf / self.__sf)
-            _o = other.__v
-       elif self.__s > other.__s:
-            _s = self.__v
-            _o = other.__v * (self.__sf / other.__sf)
-        else:
-            _s = self.__v
-            _o = other.__v
-
-       mp = max(self.__p - self.__s, other.__p - other.__s)
-       ms = max(self.__s, other.__s)
-       return PgNumeric((_s - _o), (mp + ms), ms)
-
-    def __rsub__(self, other):
-       return other.__sub__(self)
-        
-    def __isub__(self, other):
-        _r = self.__sub__(other)
-        if _r is None:
-            return None
-        self.__v  = _r.__v
-        self.__p  = _r.__p
-        self.__s  = _r.__s
-        self.__sf = _r.__sf
-       return self
-
-    def __mul__(self, other):
-        _c = self.__coerce__(other)
-        if _c is None:
-            return None
-        self, other = _c
-       _p = self.__v * other.__v
-       return PgNumeric(_p, self.__p + other.__p, self.__s + other.__s)
-
-    def __rmul__(self, other):
-       return self.__mul__(self, other)
-
-    def __imul__(self, other):
-        _r = self.__mul__(other)
-        if _r is None:
-            return None
-        self.__v  = _r.__v
-        self.__p  = _r.__p
-        self.__s  = _r.__s
-        self.__sf = _r.__sf
-       return self
-
-    def __div__(self, other):
-        _c = self.__coerce__(other)
-        if _c is None:
-            return None
-        self, other = _c
-       _n = self.__v * other.__sf * self.__sf
-       _d = other.__v
-       _q = self._round((_n / _d), self.__s)
-       return PgNumeric(_q, self.__p, self.__s)
-
-    def __rdiv__(self, other):
-       return other.__div__(self)
-
-    def __idiv__(self, other):
-        _r = self.__div__(other)
-        if _r is None:
-            return None
-        self.__v  = _r.__v
-        self.__p  = _r.__p
-        self.__s  = _r.__s
-        self.__sf = _r.__sf
-       return self
-
-    def __cmp__(self, other):
-        if other is None:
-            return 1
-        _c = self.__coerce__(other)
-        if _c is None:
-            return None
-        self, other = _c
-       if self.__s < other.__s:
-           _s = self.__v * (other.__sf / self.__sf)
-           _o = other.__v
-       elif self.__s > other.__s:
-           _s = self.__v
-           _o = other.__v * (self.__sf / other.__sf)
-       else:
-           _s = self.__v
-           _o = other.__v
-       return cmp(_s, _o)
-
-    def __neg__(self):
-       return PgNumeric(-self.__v, self.__p, self.__s)
-
-    def __nonzero__(self):
-       return self.__v not in (None, 0)
-
-    def __pos__(self):
-       return PgNumeric(self.__v, self.__p, self.__s)
-
-    def __abs__(self):
-       if self.__v >= 0:
-           return PgNumeric(self.__v, self.__p, self.__s)
-       else:
-           return PgNumeric(-self.__v, self.__p, self.__s)
-
-    def _quote(self, forArray=0):
-       if self.__v:
-           if forArray:
-               return '"%s"' % self.__fmtNumeric()
-           else:
-               return "'%s'" % self.__fmtNumeric()
-       return 'NULL'
-
-    def __int__(self):
-       return int(self.__v / self.__sf)
-
-    def __long__(self):
-       return self.__v / self.__sf
-
-    def __float__(self):
-       v = self.__v
-       s = self.__sf
-       return (float(v / s) + (float(v % s) / float(s)))
-
-    def __complex__(self):
-       return complex(self.__float__())
-
-    def __hash__(self):
-       if self.__s == 0:
-           return hash(self.__v)
-       v = self.__v / self.__sf
-       if (v * self.__sf) == self.__v:
-           return hash(v)
-       return hash(float(self))
-
-#-----------------------------------------------------------------------+
-# Name:                PgMoney                                                 |
-#                                                                      |
-# Description: A Python wrapper class for the PostgreSQL Money type.   |
-#              It's primary purpose it to check for overflow during    |
-#              calulations and to provide formatted output.            |
-#                                                                      |
-# Note:                The PgMoney class uses a Python Floating point number   |
-#              represent a PostgreSQL money type.                      |
-#-----------------------------------------------------------------------+
-
-class PgMoney:
-    def __init__(self, value):
-       if value is None:
-           self.value = value
-           return
-
-       if type(value) is StringType:
-           if value[0] == '(':
-               self.value = PgMoney(-float(replace(value[2:-1], ',', '')))
-           elif value[0] == '-':
-               self.value = PgMoney(-float(replace(value[2:], ',', '')))
-           else:
-               self.value = PgMoney(float(replace(value[1:], ',', '')))
-       else:
-           self.value = float(value)
-
-       if self.value < -21474836.48 or self.value > 21474836.47:
-           raise OverflowError, 'money initialization'
-       
-
-    def __checkresult(self, value, op):
-       if value < -21474836.48 or value > 21474836.47:
-           raise OverflowError, 'money %s' % op
-       return PgMoney(value)
-
-    def __coerce__(self, other):
-       if other is None:
-           return None
-       res = coerce(self.value, other)
-       if res is None:
-           return None
-       _s, _o = res
-       return (self, _o)
-
-    def __hash__(self):
-       return hash(self.value)
-
-    def __cmp__(self, other):
-        return cmp(self.value, other)
-
-    def __add__(self, other):
-       return self.__checkresult(self.value + other, "addition")
-
-    def __sub__(self, other):
-       return self.__checkresult(self.value - other, "subtraction")
-
-    def __mul__(self, other):
-       return self.__checkresult(self.value * other, "mulitplication")
-
-    def __div__(self, other):
-       return self.__checkresult(self.value / other, "division")
-
-    def __divmod__(self, other):
-       _a, _b = divmod(self.value, other)
-       return (self.__checkresult(_a, "divmod"), _b)
-
-    def __pow__(self, other, modulus=None):
-       return self.__checkresult(pow(self.value, other, modulus), "pow")
-
-    def __radd__(self, other):
-       return self.__checkresult(other + self.value, "addition")
-
-    def __rsub__(self, other):
-       return self.__checkresult(other - self.value, "subtraction")
-
-    def __rmul__(self, other):
-       return self.__checkresult(other * self.value, "multiplication")
-
-    def __rdiv__(self, other):
-       return self.__checkresult(other / self.value, "division")
-
-    def __rdivmod__(self, other):
-       _a, _b = divmod(other, self.value)
-       return (self.__checkresult(_a, "divmod"), _b)
-
-    def __rpow__(self, other, modulus=None):
-       return self.__checkresult(pow(other, self.value, modulus), "pow")
-
-    def __neg__(self):
-       return self.__checkresult(self.value * -1, "negation")
-
-    def __pos__(self):
-       return self.value
-
-    def __abs__(self):
-       return self.__checkresult(abs(self.value), "abs")
-
-    def __complex__(self):
-       return complex(self.value)
-
-    def __int__(self):
-       return int(self.value)
-
-    def __long__(self):
-       return long(self.value)
-
-    def __float__(self):
-       return self.value       # PgMoney is already a float :-)
-
-    def __repr__(self):
-       return '%.2f' % self.value
-
-    def __str__(self):
-       _s = '%.2f' % abs(self.value)
-       _i = string.rfind(_s, '.')
-       _c = (_i - 1) / 3
-       for _j in range(_c):
-           _i = _i - 3
-           _s = '%s,%s' % (_s[:_i], _s[_i:])
-       if self.value < 0.0:
-           return '($%s)' % _s
-       else:
-           return '$%s' % _s
-
-    def _quote(self, forArray=0):
-       if self.value:
-           if forArray:
-               return '"%s"' % str(self.value)
-           else:
-               return "'%s'" % str(self.value)
-       return 'NULL'
-
-#-----------------------------------------------------------------------+
-# Name:                PgInt8                                                  |
-#                                                                      |
-# Description: A Python wrapper class for the PostgreSQL int8 type.    |
-#              It's primary purpose it to check for overflow during    |
-#              calulations.                                            |
-#                                                                      |
-# Note:                The PgInt8 class uses a Python Long Integer to hold     |
-#              the PostgreSQL int8 type.                               |
-#                                                                      |
-# Note:                This class will only be defined if the C implementation |
-#              of the PgInt8 object was not imported with/from libpq.  |
-#-----------------------------------------------------------------------+
-
-if dir().count('PgInt8') == 0: # Only define this class is PgInt8 wasn't
-                               # brought in via libpq.
-    class PgInt8:
-       def __init__(self, value):
-           if value is None:
-               self.value = value
-               return
-
-           self.value = long(value)
-           if self.value < -9223372036854775808L or \
-              self.value > 9223372936854775807L:
-               raise OverflowError, 'int8 initialization'
-
-       def __checkresult(self, value, op):
-           if value < -9223372036854775808L or value > 9223372936854775807L:
-               raise OverflowError, 'int8 %s' % op
-           return PgInt8(value)
-
-       def __coerce__(self, other):
-           if other is None:
-               return None
-           res = coerce(self.value, other)
-           if res is None:
-               return None
-           _s, _o = res
-           return (self, _o)
-
-       def __hash__(self):
-           return hash(self.value)
-
-       def __cmp__(self, other):
-            return cmp(self.value, other)
-
-       def __nonzero__(self):
-           return self.value != 0
-
-       def __add__(self, other):
-           return self.__checkresult(self.value + other, "addition")
-
-       def __sub__(self, other):
-           return self.__checkresult(self.value - other, "subtraction")
-
-       def __mul__(self, other):
-           return self.__checkresult(self.value * other, "mulitplication")
-
-       def __div__(self, other):
-           return self.__checkresult(self.value / other, "division")
-
-       def __divmod__(self, other):
-           _a, _b = divmod(self.value, other)
-           return (self.__checkresult(_a, "divmod"), _b)
-
-       def __pow__(self, other, modulus=None):
-           return self.__checkresult(pow(self.value, other, modulus), "pow")
-
-       def __lshift__(self, other):
-           return self.__checkresult(self.value << other, 'lshift')
-
-       def __rshift__(self, other):
-           return self.__checkresult(self.value >> other, 'rshift')
-
-       def __and__(self, other):
-           return self.__checkresult(self.value & other, 'and')
-
-       def __xor__(self, other):
-           return self.__checkresult(self.value ^ other, 'xor')
-
-       def __or__(self, other):
-           return self.__checkresult(self.value | other, 'or')
-
-       def __radd__(self, other):
-           return self.__checkresult(other + self.value, "addition")
-
-       def __rsub__(self, other):
-           return self.__checkresult(other - self.value, "subtraction")
-
-       def __rmul__(self, other):
-           return self.__checkresult(other * self.value, "mulitplication")
-
-       def __rdiv__(self, other):
-           return self.__checkresult(other / self.value, "division")
-
-       def __rdivmod__(self, other):
-           _a, _b = divmod(other, self.value)
-           return (self.__checkresult(_a, "divmod"),
-                   self.__checkresult(_b, "divmod"))
-
-       def __rpow__(self, other, modulus=None):
-           return self.__checkresult(pow(other, self.value, modulus), "pow")
-
-       def __rlshift__(self, other):
-           return self.__checkresult(other << self.value, 'lshift')
-
-       def __rrshift__(self, other):
-           return self.__checkresult(other >> self.value, 'rshift')
-
-       def __rand__(self, other):
-           return self.__checkresult(other & self.value, 'and')
-
-       def __rxor__(self, other):
-           return self.__checkresult(other ^ self.value, 'xor')
-
-       def __ror__(self, other):
-           return self.__checkresult(other | self.value, 'or')
-
-       def __neg__(self):
-           return self.__checkresult(neg(self.value), 'neg')
-
-       def __pos__(self):
-           return self.__checkresult(pos(self.value), 'pos')
-
-       def __abs__(self):
-           return self.__checkresult(abs(self.value), 'abs')
-
-       def __complex__(self):
-           return complex(self)
-
-       def __int__(self):
-           return int(self.value)
-
-       def __long__(self):
-           return self.value   # PgInt8 is already a Long.
-
-       def __float__(self):
-           return float(self.value)
-
-       def __complex__(self):
-           return complex(self.value)
-
-       def __hex__(self):
-           return hex(self.value)
-
-       def __oct__(self):
-           return oct(self.value)
-
-       def __repr__(self):
-           return repr(self.value)
-
-       def __str__(self):
-           return str(self.value)
-
-       def _quote(self, forArray=0):
-           if self.value is not None:
-               s = str(self.value)
-               if s[-1:] == "L":
-                   s = s[:-1]
-               return "%s" % s
-           return 'NULL'
-
-    PgInt8Type = PgInt8
-
-
-#-----------------------------------------------------------------------+
-# Name:                PgResultSet                                             |
-#                                                                      |
-# Description: This class defines the DB-API query result set for a    |
-#              single row.  It emulates a sequence  with the added     |
-#              feature of being able to reference an attribute by      |
-#              column name in addition to a zero-based numeric index.  |
-#                                                                      |
-#              This class isn't used directly, instead it's used as a  |
-#              base class for the actual result set class created with |
-#              make_PgResultSetClass.                                  |
-#                                                                      |
-#-----------------------------------------------------------------------+
-
-class PgResultSet:
-
-    # It may not be obvious what self.__class__ does:
-    # Apart from the __init__ method, all methods are called on instances of a
-    # class dynamically created make_PgResultSetClass, which means that when
-    # you call a method, self.__class__ is *not* PgResultSet, but a subclass of
-    # it created with make_PgResultSetClass (using the new module). The
-    # subclass will have a class attribute called _xlatkey, which is a mapping
-    # of column names to column positions.
-    
-    def __init__(self, value):
-       self.__dict__['baseObj'] = value
-
-    def __getattr__(self, key):
-        # When retrieving column data by name as an attribute, we must be
-        # aware that a column name can be defiend with mixed-case within the
-        # database.  Because of this we must first check for an exact match
-        # with the given key.  If that fails, then we match with the key that
-        # has been changed to lower case.  Note: we are relying on the fact
-        # that PostgreSQL sends column names that are not defined with mixed-
-        # case to the client as lower-case names.
-        keyl = key.lower()
-       if self._xlatkey.has_key(key):
-           return self.baseObj[self._xlatkey[key]]
-       if self._xlatkey.has_key(keyl):
-           return self.baseObj[self._xlatkey[keyl]]
-       raise AttributeError, key
-
-    # We define a __setattr__ routine that will only allow the attributes that
-    # are the column names to be updated.  All other attributes are read-only.
-    def __setattr__(self, key, value):
-       if key in ('baseObj', '_xlatkey', '_desc_'):
-           raise AttributeError, "%s is read-only." % key
-
-        # Try an exact match first, then the case-insensitive match.
-        # See comment in __getattr__ for details.
-       keyl = key.lower()
-       if self._xlatkey.has_key(key):
-           self.__dict__['baseObj'][self._xlatkey[key]] = value
-       elif self._xlatkey.has_key(keyl):
-           self.__dict__['baseObj'][self._xlatkey[keyl]] = value
-       else:
-           raise AttributeError, key
-
-    def __len__(self):
-       return len(self.baseObj)
-
-    def __getitem__(self, key):
-       if isinstance(key, StringType):
-            # Try an exact match first, then the case-insensitive match.
-            # See comment in __getattr__ for details.
-            try:
-                key = self._xlatkey[key]
-            except:
-                key = self._xlatkey[key.lower()]
-       return self.baseObj[key]
-
-    def __setitem__(self, key, value):
-       if isinstance(key, StringType):
-            # Try an exact match first, then the case-insensitive match.
-            # See comment in __getattr__ for details.
-            try:
-                key = self._xlatkey[key]
-            except:
-                key = self._xlatkey[key.lower()]
-       self.baseObj[key] = value
-
-    def __contains__(self, key):
-       return self.has_key(key)
-
-    def __getslice__(self, i, j):
-       klass = make_PgResultSetClass(self._desc_[i:j])
-       obj = klass(self.baseObj[i:j])
-       return obj
-
-    def __repr__(self):
-       return repr(self.baseObj)
-
-    def __str__(self):
-       return str(self.baseObj)
-
-    def __cmp__(self, other):
-       return cmp(self.baseObj, other)
-
-    def description(self):
-       return self._desc_
-
-    def keys(self):
-       _k = []
-       for _i in self._desc_:
-           _k.append(_i[0])
-       return _k
-
-    def values(self):
-       return self.baseObj[:]
-
-    def items(self):
-       _items = []
-       for i in range(len(self.baseObj)):
-           _items.append((self._desc_[i][0], self.baseObj[i]))
-       return _items
-
-    def has_key(self, key):
-        # Try an exact match first, then the case-insensitive match.
-        # See comment in __getattr__ for details.
-        if not self._xlatkey.has_key(key):
-            key = key.lower()
-       return self._xlatkey.has_key(key)
-
-    def get(self, key, defaultval=None):
-       try:
-            if isinstance(key, StringType):
-                # Try an exact match first, then the case-insensitive match.
-                # See comment in __getattr__ for details.
-                try:
-                    key = self._xlatkey[key]
-                except:
-                    key = self._xlatkey[key.lower()]
-            return self[key]
-       except:
-           return defaultval
-
-def make_PgResultSetClass(description, mapname=None):
-    """Dynamically create a new subclass of PgResultSet."""
-    klass = new.classobj("PgResultSetConcreteClass", (PgResultSet,), {})
-    klass.__dict__['_desc_'] = description
-
-    klass.__dict__['_xlatkey'] = {}
-    if mapname is None:
-       for _i in range(len(description)):
-           klass.__dict__['_xlatkey'][description[_i][0]] = _i
-    else:
-       for k, v in mapname.items():
-           klass.__dict__['_xlatkey'][k] = v
-    return klass 
-
-
-#-----------------------------------------------------------------------+
-# Define the PgSQL function calls:                                     |
-#                                                                      |
-#      connect()      -- connect to a PostgreSQL database.             |
-#      _handleArray() -- Transform a PgArray class into a string rep-  |
-#                        resenting a PostgreSQL array.                 |
-#      _quote()       -- Transform a Python object representing a      |
-#                        PostgreSQL type into a appropiately quoted    |
-#                        string that can be sent to the database in a  |
-#                        UPDATE/INSERT statement.  _quote() calls the  |
-#                        _handleArray() function to quote arrays.      |
-#       _quoteall()    -- transforms all elements of a list or diction-        |
-#                        ary using _quote.                             |
-#       dateTimeDelta2Interval() -- converts a DateTimeDelta type into |
-#                        a string PostgreSQL accepts as a interval.    |
-#-----------------------------------------------------------------------+
-
-def connect(dsn=None, user=None, password=None, host=None, database=None,
-               port=None, options=None, tty=None, client_encoding=None,
-               unicode_results=None):
-    """
-connection =  PgSQL.connect(dsn[, user, password, host, database, port,
-                                 options, tty] [, client_encoding] 
-                                 [, unicode_results])
-    Opens a connection to a PostgreSQL database."""
-       
-    _d = {}
-
-    # Try getting values from the DSN first.
-    if dsn is not None:
-       try:
-           params = string.split(dsn, ":")
-           if params[0] != '': _d["host"]     = params[0]
-           if params[1] != '': _d["port"]     = params[1]
-           if params[2] != '': _d["dbname"]   = params[2]
-           if params[3] != '': _d["user"]     = params[3]
-           if params[4] != '': _d["password"] = params[4]
-           if params[5] != '': _d["options"]  = params[5]
-           if params[6] != '': _d["tty"]      = params[6]
-       except:
-           pass
-
-    # Override from the keyword arguments, if needed.
-    if (user is not None):     _d["user"]      = user
-    if (password is not None): _d["password"]  = password
-    if (host is not None):
-       _d["host"] = host
-       try:
-           params = string.split(host, ":")
-           _d["host"] = params[0]
-           _d["port"] = params[1]
-       except:
-           pass
-    if (database is not None): _d["dbname"]    = database
-    if (port is not None):     _d["port"]      = port
-    if (options is not None):  _d["options"]   = options
-    if (tty is not None):      _d["tty"]       = tty
-
-    # Build up the connection info string passed to PQconnectdb
-    # via the constructor to Connection.
-
-    connInfo = ""
-    for i in _d.keys():
-       connInfo = "%s%s=%s " % (connInfo, i, _d[i])
-       
-    return Connection(connInfo, client_encoding, unicode_results)
-
-def _handleArray(value):
-    """
-_handleArray(list) -> string
-    This function handle the transformation of a Python list into a string that
-    can be used to update a PostgreSQL array attribute."""
-
-    #Check for, and handle an empty list.
-    if len(value) == 0:
-       return '{}'
-
-    _j = "'{"
-    for _i in value:
-       if _i is None:
-           _j += ","
-       elif isinstance(_i, PgArray):
-           _j = _j + _handleArray(_i)[1:-1] + ','
-       elif hasattr(_i, '_quote'):
-           _j = '%s%s,' % (_j, _i._quote(1))
-       elif type(_i) is DateTimeType:
-           _j = '%s"%s",' % (_j, _i)
-       elif type(_i) is DateTime.DateTimeDeltaType:
-           _j = '%s"%s",' % (_j, dateTimeDelta2Interval(_i))
-       elif type(_i) is PgInt2Type or isinstance(_i, PgInt8Type):
-           _j = '%s%s,' % (_j, str(_i))
-       else:
-           _j = '%s%s,' % (_j, PgQuoteString(str(_i), 1))
-
-    return _j[:-1] + "}'"
-
-def _quote(value):
-    """
-_quote(value) -> string
-    This function transforms the Python value into a string suitable to send
-    to the PostgreSQL database in a insert or update statement.  This function
-    is automatically applied to all parameter sent vis an execute() call.
-    Because of this an update/insert statement string in an execute() call
-    should only use '%s' [or '%(name)s'] for variable subsitution without any
-    quoting."""
-
-    if value is None:
-       return 'NULL'
-    elif hasattr(value, '_quote'):
-       return value._quote()
-    elif type(value) is DateTimeType:
-       return "'%s'" % value
-    elif type(value) is DateTimeDeltaType:
-       return "'%s'" % dateTimeDelta2Interval(value)
-    elif isinstance(value, StringType):
-       return PgQuoteString(value)
-    elif isinstance(value, LongType):
-        return str(value)
-    else:
-       return repr(value)
-
-def _quoteall(vdict):
-    """
-_quoteall(vdict)->dict
-    Quotes all elements in a list or dictionary to make them suitable for
-    insertion."""
-
-    if type(vdict) is DictType or isinstance(vdict, PgResultSet):
-       t = {}
-       for k, v in vdict.items():
-           t[k]=_quote(v)
-    elif type(vdict) in (StringType, UnicodeType):
-       # Note: a string is a SequenceType, but is treated as a single
-       #       entity, not a sequence of characters.
-       t = (_quote(vdict), )
-    elif type(vdict) in [ListType, TupleType]:
-       t = tuple(map(_quote, vdict))
-    else:
-       raise TypeError, \
-             "argument to _quoteall must be a sequence or dictionary!"
-
-    return t
-
-def dateTimeDelta2Interval(interval):
-    """
-DateTimeDelta2Interval - Converts a DateTimeDelta to an interval string\n
-    The input format is [+-]DD:HH:MM:SS.ss\n
-    The output format is DD days HH:MM:SS.ss [ago]\n
-    """
-
-    if type(interval) is DateTimeDeltaType:
-       s = str(interval)
-       ago = ''
-       if s[0] == '-':
-           ago = ' ago'
-           s = s[1:]
-       else:
-           ago = ''
-       s = s.split(':')
-       if len(s) < 4:
-           return '%s:%s:%s %s' % (s[0], s[1], s[2], ago)
-
-       return '%s days %s:%s:%s %s' % (s[0], s[1], s[2], s[3], ago)
-    else:
-       raise TypeException, "DateTimeDelta2Interval requires a DataTimeDelta."
-
-#-----------------------------------------------------------------------+
-# Name:                Connection                                              |
-#                                                                      |
-# Description: Connection defines the Python DB-API 2.0 connection     |
-#              object.  See the DB-API 2.0 specifiaction for details.  |
-#-----------------------------------------------------------------------+
-
-class Connection:
-    """Python DB-API 2.0 Connection Object."""
-
-    def __init__(self, connInfo, client_encoding=None, unicode_results=None):
-       try:
-           self.__dict__["conn"] = PQconnectdb(connInfo)
-       except Exception, m:
-           # The connection to the datadata failed.
-           # Clean up the Connection object that was created.
-           # Note: _isOpen must be defined for __del__ to work.
-           self.__dict__["_isOpen"] = None
-           del(self)
-           raise DatabaseError, m
-           
-       self.__dict__["autocommit"] = 0
-       self.__dict__["TransactionLevel"] = ""
-       self.__dict__["notices"] = self.conn.notices
-       self.__dict__["inTransaction"] = 0
-       self.__dict__["version"] = self.conn.version
-       self.__dict__["_isOpen"] = 1
-       self.__dict__["_cache"] = TypeCache(self)
-       if noWeakRef:
-           self.__dict__["cursors"] = []
-       else:
-           self.__dict__["cursors"] = weakref.WeakValueDictionary()
-
-       self.unicode_results = unicode_results
-       if type(client_encoding) in (TupleType, ListType):
-           self.client_encoding = client_encoding
-       else:
-           self.client_encoding = (client_encoding or getdefaultencoding(),)
-
-    def __del__(self):
-       if self._isOpen:
-           self.close()        # Ensure that the connection is closed.
-
-    def __setattr__(self, name, value):
-       if name == "autocommit":
-           if value is None:
-               raise InterfaceError, \
-                   "Can't delete the autocommit attribute."
-           # Don't allow autocommit to change if there are any opened cursor
-           # associated with this connection.
-           if self.__anyLeft():
-               if noWeakRef:
-                   # If the are cursors left, but weak references are not
-                   # available, garbage collect any cursors that are only
-                   # referenced in self.cursors.
-
-                   self.__gcCursors()
-
-                   if len(self.cursors) > 0:
-                       raise AttributeError, \
-                           "Can't change autocommit when a cursor is active."
-               else:
-                   raise AttributeError, \
-                       "Can't change autocommit when a cursor is active."
-
-           # It's possible that the connection can still have an open
-           # transaction, even though there are no active cursors.
-
-           if self.inTransaction:
-               self.rollback()
-
-           if value:
-               self.__dict__[name] = 1
-           else:
-               self.__dict__[name] = 0
-       elif name == "TransactionLevel":
-           if value is None:
-               raise InterfaceError, \
-                   "Can't delete the TransactinLevel attribute."
-           # Don't allow TransactionLevel to change if there are any opened
-           # cursors associated with this connection.
-           if self.__anyLeft():
-               if noWeakRef:
-                   # If the are cursors left, but weak references are not
-                   # available, garbage collect any cursors that are only
-                   # referenced in self.cursors.
-
-                   self.__gcCursors()
-
-                   if len(self.cursors) > 0:
-                       raise AttributeError, \
-                       "Can't change TransactionLevel when a cursor is active."
-               else:
-                   raise AttributeError, \
-                       "Can't change TransactionLevel when a cursor is active."
-
-           # It's possible that the connection can still have an open
-           # transaction, even though there are no active cursors.
-
-           if self.inTransaction:
-               self.rollback()
-
-           if type(value) is not StringType:
-               raise ValueError, "TransactionLevel must be a string."
-
-           if value.upper() in [ "", "READ COMMITTED", "SERIALIZABLE" ]:
-               self.__dict__[name] = value.upper()
-           else:
-               raise ValueError, \
-           'TransactionLevel must be: "", "READ COMMITTED", or "SERIALIZABLE"'
-       elif name in ('unicode_results', 'client_encoding'):
-           self.__dict__[name] = value
-       elif self.__dict__.has_key(name):
-           raise AttributeError, "%s is read-only." % name
-       else:
-            raise AttributeError, name
-
-    def __closeCursors(self, flag=0):
-       """
-       __closeCursors() - closes all cursors associated with this connection"""
-       if self.__anyLeft():
-           if noWeakRef:
-               curs = self.cursors[:]
-           else:
-               curs = map(lambda x: x(), self.cursors.data.values())
-
-           for i in curs:
-               if flag:
-                   i.close()
-               else:
-                   i._Cursor__reset()
-
-       return self.inTransaction
-
-    def __anyLeft(self):
-       if noWeakRef:
-           return len(self.cursors) > 0
-
-       return len(self.cursors.data.keys()) > 0
-
-    def __gcCursors(self):
-       # This routine, which will be called only if weak references are not
-       # available, will check the reference counts of the cursors in the
-       # connection.cursors list and close any that are only referenced
-       # from that list.  This will clean up deleted cursors.
-
-       for i in self.cursors[:]:
-           # Check the reference count.  It will be 4 if it only exists in
-           # self.cursors.  The magic number for is derived from the fact
-           # that there will be 1 reference count for each of the follwoing:
-           #     self.cursors, self.cursors[:], i, and as the argument to
-           #     getrefcount(),
-
-           if getrefcount(i) < 5:
-               i.close()
-
-    def __setupTransaction(self):
-        """
-    __setupTransaction()
-        Internal routine that will set up a transaction for this connection.\n"""
-        self.conn.query("BEGIN WORK")
-        if self.TransactionLevel != "":
-           _nl = len(self.notices)
-            self.conn.query('SET TRANSACTION ISOLATION LEVEL %s' %
-                                 self.TransactionLevel)
-            if len(self.notices) != _nl:
-                raise Warning, self.notices.pop()
-        self.__dict__["inTransaction"] = 1
-
-        
-    def close(self):
-       """
-    close()
-       Close the connection now (rather than whenever __del__ is called).
-       Any active cursors for this connection will be closed and the connection
-       will be unusable from this point forward.\n"""
-
-       if not self._isOpen:
-           raise InterfaceError, "Connection is already closed."
-
-       if self.__closeCursors(1):
-           try:
-               _nl = len(self.conn.notices)
-               self.conn.query("ROLLBACK WORK")
-               if len(self.notices) != _nl:
-                   raise Warning, self.notices.pop()
-           except:
-               pass
-
-       self.__dict__["_cache"] = None
-       self.__dict__["_isOpen"] = 0
-       self.__dict__["autocommit"] = None
-       self.__dict__["conn"] = None
-       self.__dict__["cursors"] = None
-       self.__dict__["inTransaction"] = 0
-       self.__dict__["TransactionLevel"] = None
-       self.__dict__["version"] = None
-       self.__dict__["notices"] = None
-
-    def commit(self):
-       """
-    commit()
-       Commit any pending transactions to the database.\n"""
-
-       if not self._isOpen:
-           raise InterfaceError, "Commit failed - Connection is not open."
-
-       if self.autocommit:
-           raise InterfaceError, "Commit failed - autocommit is on."
-
-       if self.__closeCursors():
-           self.__dict__["inTransaction"] = 0
-           _nl = len(self.conn.notices)
-           res = self.conn.query("COMMIT WORK")
-           if len(self.notices) != _nl:
-               raise Warning, self.notices.pop()
-           if res.resultStatus != COMMAND_OK:
-               raise InternalError, "Commit failed - reason unknown."
-
-    def rollback(self):
-       """
-    rollback()
-       Rollback to the start of any pending transactions.\n"""
-
-       if not self._isOpen:
-           raise InterfaceError, "Rollback failed - Connection is not open."
-
-       if self.autocommit:
-           raise InterfaceError, "Rollback failed - autocommit is on."
-
-       if self.__closeCursors():
-           self.__dict__["inTransaction"] = 0
-           _nl = len(self.conn.notices)
-           res = self.conn.query("ROLLBACK WORK")
-           if len(self.notices) != _nl:
-               raise Warning, self.notices.pop()
-           if res.resultStatus != COMMAND_OK:
-               raise InternalError, \
-                       "Rollback failed - %s" % res.resultErrorMessage
-
-    def cursor(self, name=None, isRefCursor=PG_False):
-       """
-    cursor([name])
-       Returns a new 'Cursor Object' (optionally named 'name')."""
-
-       if not self._isOpen:
-           raise InterfaceError, \
-                 "Create cursor failed - Connection is not open."
-
-       return Cursor(self, name, isRefCursor)
-
-    def binary(self, string=None):
-       """
-    binary([string])
-       Returns a new 'Large Object'.  If sting is present, it is used to
-       initialize the large object."""
-
-       if not self._isOpen:
-           raise InterfaceError, \
-                 "Creation of large object failed - Connection is not open."
-
-        if self.autocommit:
-            raise InterfaceError, \
-                  "Creation of large object failed - autocommit is on."
-        
-       _nl = len(self.notices)
-        _ct = 0
-       # Ensure that we are in a transaction for working with large objects
-       if not self.inTransaction:
-            self.__setupTransaction()
-            _ct = 1
-
-       _lo = self.conn.lo_creat(INV_READ | INV_WRITE)
-
-       if len(self.notices) != _nl:
-           raise Warning, self.notices.pop()
-
-       if string:
-           _lo.open("w")
-           _lo.write(string)
-           _lo.close()
-       
-           if len(self.notices) != _nl:
-               if self.inTransaction:
-                   self.conn.query("ROLLBACK WORK")
-               raise Warning, self.conn.notices.pop()
-
-       return _lo
-
-    def unlink(self, lobj):
-       """
-    unlink(OID|PgLargeObject)
-       Remove a large object from the database inversion file syste."""
-
-       if not self._isOpen:
-           raise InterfaceError, \
-                 "Unlink of large object failed - Connection is not open."
-
-       if not self.version.post70 and self.inTransaction:
-           raise NotSupportedError, \
-                 "unlink of a PostgreSQL Large Object in a transaction"
-
-       if type(lobj) is IntType:
-           oid = lobj
-       elif type(lobj) is PgLargeObjectType:
-           oid = lobj.oid
-
-       _nl = len(self.conn.notices)
-       res = self.conn.lo_unlink(oid)
-       if len(self.notices) != _nl:
-           raise Warning, self.notices.pop()
-
-       return res
-
-#-----------------------------------------------------------------------+
-# Name:                Cursor                                                  |
-#                                                                      |
-# Description: Cursor defines the Python DB-API 2.0 cursor object.     |
-#              See the DB-API 2.0 specification for details.           |
-#-----------------------------------------------------------------------+
-
-class Cursor:
-    """Python DB-API 2.0 Cursor Object."""
-
-    def __init__(self, conn, name, isRefCursor=PG_False):
-       if not isinstance(conn, Connection):
-           raise TypeError, "Cursor requires a connection."
-
-       # Generate a unique name for the cursor is one is not given.
-       if name is None:
-            if isRefCursor:
-                raise TypeError, "Reference cursor requires a name."
-           name = "PgSQL_%08X" % id(self)
-       elif type(name) is not StringType:
-           raise TypeError, "Cursor name must be a string."
-
-       # Define the public variables for this cursor.
-       self.__dict__["arraysize"] = 1
-
-       # Define the private variables for this cursor.
-       if noWeakRef:
-           self.__dict__["conn"]    = conn
-       else:
-           self.__dict__["conn"]    = weakref.proxy(conn)
-       self.__dict__["name"]        = name
-
-       # This needs to be defined here sot that the initial call to __reset()
-       # will work.
-        self.__dict__["closed"] = None
-        self.__reset()
-
-       # _varhdrsz is the length (in bytes) of the header for variable
-       # sized postgreSQL data types.
-
-       self.__dict__["_varhdrsz"] = 4
-
-       # Add ourselves to the list of cursors for our owning connection.
-       if noWeakRef:
-           self.conn.cursors.append(self)
-           if len(self.conn.cursors) > 1:
-               # We have additional cursors, garbage collect them.
-               self.conn._Connection__gcCursors()
-       else:
-           self.conn.cursors[id(self)] = self
-
-       if not self.conn.autocommit:
-           # Only the first created cursor begins the transaction.
-           if not self.conn.inTransaction:
-                self.conn._Connection__setupTransaction()
-       self.__dict__["PgResultSetClass"] = None
-        
-        if isRefCursor:
-           # Ok -- we've created a cursor, we will pre-fetch the first row in
-           # order to make the description array.  Note: the first call to
-           # fetchXXX will return the pre-fetched record.
-            self.__dict__["closed"] = 0
-           self.res = self.conn.conn.query('FETCH 1 FROM "%s"' % self.name)
-           self._rows_ = self.res.ntuples
-           self._idx_ = 0
-           self.__makedesc__()
-
-    def __del__(self):
-       # Ensure that the cursor is closed when it is deleted.  This takes
-       # care of some actions that needs to be completed when a cursor is
-       # deleted, such as disassociating the cursor from the connection
-       # and closing an open transaction if this is the last cursor for
-       # the connection.
-       if not self.closed:
-           self.close()
-
-    def __reset(self):
-       try:
-           if (self.closed == 0) and self.conn.inTransaction:
-               try:
-                   self.conn.conn.query('CLOSE "%s"' % self.name)
-               except:
-                   pass
-       except:
-           pass
-
-       self.__dict__["res"]         = None
-       # closed is a trinary variable:
-       #     == None => Cursor has not been opened.
-       #     ==    0 => Cursor is open.
-       #     ==    1 => Curosr is closed.
-       self.__dict__["closed"]    = None
-       self.__dict__["description"] = None
-       self.__dict__["oidValue"]    = None
-       self.__dict__["_mapname"]    = None
-       self.__dict__["_rows_"]      = 0
-       self.__dict__["_idx_"]       = 1
-       self.__dict__["rowcount"]    = -1
-
-    def __setattr__(self, name, value):
-       if self.closed:
-           raise InterfaceError, "Operation failed - the cursor is closed."
-
-       if name in ["rowcount", "oidValue", "description"]:
-           raise AttributeError, "%s is read-only." % name
-       elif self.__dict__.has_key(name):
-           self.__dict__[name] = value
-       else:
-           raise AttributeError, name
-       
-    def __unicodeConvert(self, obj):
-       if type(obj) is StringType:
-           return obj
-       elif type(obj) is UnicodeType:
-           return obj.encode(*self.conn.client_encoding)
-       elif type(obj) in (ListType, TupleType):
-           converted_obj = []
-           for item in obj:
-               if type(item) is UnicodeType:
-                   converted_obj.append(item.encode(*self.conn.client_encoding))
-               else:
-                   converted_obj.append(item)
-           return converted_obj
-       elif type(obj) is DictType:
-           converted_obj = {}
-           for k, v in obj.items():
-               if type(v) is UnicodeType:
-                   converted_obj[k] = v.encode(*self.conn.client_encoding)
-               else:
-                   converted_obj[k] = v
-           return converted_obj
-       elif isinstance(obj, PgResultSet):
-           obj = copy.copy(obj)
-           for k, v in obj.items():
-               if type(v) is UnicodeType:
-                   obj[k] = v.encode(*self.conn.client_encoding)
-           return obj
-       else:
-           return obj
-    def __fetchOneRow(self):
-       if self._idx_ >= self._rows_:
-           self.__dict__['rowcount'] = 0
-           return None
-
-       _j = []
-       _r = self.res
-       _c = self.conn._cache
-       for _i in range(self.res.nfields):
-           _j.append(_c.typecast(self.description[_i],
-                                 _r.getvalue(self._idx_, _i)))
-       
-       self._idx_ = self._idx_ + 1
-
-       self.__dict__['rowcount'] = 1
-
-       if fetchReturnsList:
-           # Return a list (This is the minimum required by DB-API 2.0
-           # compliance).
-           return _j
-       else:
-            return self.PgResultSetClass(_j)
-
-    def __fetchManyRows(self, count, iList=[]):
-       _many = iList
-       if count < 0:
-           while 1:
-               _j = self.__fetchOneRow()
-               if _j is not None:
-                   _many.append(_j)
-               else:
-                   break
-       elif count > 0:
-           for _i in range(count):
-               _j = self.__fetchOneRow()
-               if _j is not None:
-                   _many.append(_j)
-               else:
-                   break
-
-       self.__dict__['rowcount'] = len(_many)
-
-       return _many
-
-    def __makedesc__(self):
-       # Since __makedesc__ will only be called after a successful query or
-       # fetch, self.res will contain the information needed to build the
-       # description attribute even if no rows were returned.  So, we always
-       # build up the description.
-       self.__dict__['description'] = []
-       self._mapname = {}
-       _res = self.res
-       _cache = self.conn._cache
-       for _i in range(_res.nfields):
-           _j = []
-
-           _j.append(_res.fname(_i))
-
-           _typ = PgTypes(_res.ftype(_i))
-           _mod = _res.fmod(_i)
-           _tn, _pl, _ia, _bt = _cache.getTypeInfo(_typ)
-           if _ia:
-               _s, _pl, _s, _s = _cache.getTypeInfo(_bt)
-               if _bt == PG_OID:
-                   _bt = PgTypes(PG_BLOB)
-               _typ = _bt
-           elif _typ.value == PG_OID:
-               try:
-                   _p = _res.getvalue(0, _i)
-               except (ValueError, TypeError), m:
-                   # We can only guess here ...
-                   _typ = PgTypes(PG_BLOB)
-               else:
-                   if type(_p) in [PgLargeObjectType, NoneType]:
-                       _typ = PgTypes(PG_BLOB)
-                   else:
-                       _typ = PgTypes(PG_ROWID)
-
-           _j.append(_typ)
-
-           # Calculate Display size, Internal size, Precision and Scale.
-           # Note: Precision and Scale only have meaning for PG_NUMERIC
-           # columns.
-           if _typ.value == PG_NUMERIC:
-               if _mod == -1:
-                   # We have a numeric with no scale/precision.
-                   # Get them from by converting the string to a PgNumeric
-                   # and pulling them form the PgNumeric object.  If that
-                   # fails default to a precision of 30 with a scale of 6.
-                   try:
-                       nv = PgNumeric(_res.getvalue(0, _i))
-                       _p = nv.getPrecision()
-                       _s = nv.getScale()
-                   except (ValueError, TypeError), m:
-                       _p = 30
-                       _s = 6
-               else:
-                   # We hava a valid scale/precision value.  Use them.
-                   _s = _mod - self._varhdrsz
-                   _p = (_s >> 16) & 0xffff
-                   _s = _s & 0xffff
-               _j.append(None)         # Display size (always None since PG7.3)
-               _j.append(_p)           # Internal (storage) size
-               _j.append(_p)           # Precision
-               _j.append(_s)           # Scale
-           else:
-               if _pl == -1:
-                   _pl = _res.fsize(_i)
-                   if _pl == -1:
-                       _pl = _mod - self._varhdrsz
-               _j.append(None)         # Display size (always None since PG7.3)
-               _s = _res.fsize(_i)
-               if _s == -1:
-                   _s = _mod
-               _j.append(_s)           # Internal (storage) size
-               if _typ.value == PG_MONEY:
-                   _j.append(9)        # Presicion and Scale (from
-                   _j.append(2)                # the PostgreSQL doco.)
-               else:
-                   _j.append(None)             # Preision
-                   _j.append(None)             # Scale
-
-           _j.append(None)     # nullOK is not implemented (yet)
-           _j.append(_ia)      # Array indicator (PostgreSQL specific)
-
-           self.__dict__["description"].append(_j)
-
-           # Add the fieldname:fieldindex to the _mapname dictionary
-           self._mapname[_j[0]] = _i
-
-       # Create a subclass of PgResultSet. Note that we pass a copy of the
-       # description to this class.
-       self.PgResultSetClass = make_PgResultSetClass(self.description[:], self._mapname)
-
-    def callproc(self, proc, *args):
-       if self.closed:
-           raise InterfaceError, "callproc failed - the cursor is closed."
-
-       if self.conn is None:
-           raise Error, "connection is closed."
-
-       if self.closed == 0:
-           raise InterfaceError, "callproc() failed - cursor is active."
-                   
-       if self.conn.autocommit:
-           pass
-       else:
-           if not self.conn.inTransaction:
-                self.conn._Connection__setupTransaction()
-
-       proc = self.__unicodeConvert(proc)
-       args = self.__unicodeConvert(args)
-
-       _qstr = "select %s(" % proc
-       for _i in range(len(args)):
-           _qstr = '%s%s, ' % (_qstr, _quote(args[_i]))
-       if len(args) == 0:
-           _qstr = '%s)' % _qstr
-       else:
-           _qstr = '%s)' % _qstr[:-2]
-
-       _nl = len(self.conn.notices)
-
-       try:
-           self.res = self.conn.conn.query(_qstr)
-           self._rows_ = self.res.ntuples
-           self._idx_  = 0
-           if type(self.res) is not PgResultType:
-               self.__dict__['rowcount'] = -1
-           else:
-               self.__dict__['oidValue'] =  self.res.oidValue
-               if self.res.resultType == RESULT_DQL:
-                   pass
-               elif self.res.resultType == RESULT_DML:
-                   self.__dict__['rowcount'] = self.res.cmdTuples
-               else:
-                   self.__dict__['rowcount'] = -1
-       except OperationalError, msg:
-           # Uh-oh.  A fatal error occurred.  This means the current trans-
-           # action has been aborted.  Try to recover to a sane state.
-           if self.conn.inTransaction:
-               self.conn.conn.query('END WORK')
-               self.conn.__dict__["inTransaction"] = 0
-               self.conn._Connection__closeCursors()
-           raise OperationalError, msg
-       except InternalError, msg:
-           # An internal error occured.  Try to get to a sane state.
-           self.conn.__dict__["inTransaction"] = 0
-           self.conn._Connection__closeCursors_()
-           self.conn.close()
-           raise InternalError, msg
-
-       if len(self.conn.notices) != _nl:
-           _drop = self.conn.notices[-1]
-           if _drop.find('transaction is aborted') > 0:
-               raise Warning, self.conn.notices.pop()
-
-       self._rows_ = self.res.ntuples
-       self._idx_ = 0
-       self.__dict__['rowcount'] = -1    # New query - no fetch occured yet.
-       self.__makedesc__()
-
-       return None
-
-    def close(self):
-       if self.closed:
-           raise InterfaceError, "The cursor is already closed."
-
-       # Dis-associate ourselves from our cursor.
-       self.__reset()
-       try:
-           _cc = self.conn.cursors
-           if noWeakRef:
-               _cc.remove(self)
-               if (len(_cc) > 0):
-                   # We have additional cursors, garbage collect them.
-                   _cc._Connection__gcCursors()
-           else:
-               del _cc.data[id(self)]
-       except:
-           pass
-       self.conn = None
-       self.closed = 1
-
-    def execute(self, query, *parms):
-       if self.closed:
-           raise InterfaceError, "execute failed - the cursor is closed."
-
-       if self.conn is None:
-           raise Error, "connection is closed."
-
-       if self.closed == 0:
-           if re_DQL.search(query):
-               # A SELECT has already been executed with this cursor object,
-               # which means a PostgreSQL portal (may) have been opened.
-               # Trying to open another portal will cause an error to occur,
-               # so we asusme that the developer is done with the previous
-               # SELECT and reset the cursor object to it's inital state.
-               self.__reset()
-                   
-       _qstr = query
-       if self.conn.autocommit:
-           pass
-       else:
-           _badQuery = (self.conn.version < 70100) and \
-                       (re_DRT.search(query) or re_DRI.search(query))
-           if not self.conn.inTransaction:
-               if _badQuery:
-                   pass # PostgreSQL version < 7.1 and not in transaction,
-                        # so DROP TABLE/INDEX is ok.
-               else:
-                    self.conn._Connection__setupTransaction()
-
-           if re_DQL.search(query) and \
-              not (noPostgresCursor or re_4UP.search(query)):
-               _qstr = 'DECLARE "%s" CURSOR FOR %s' % (self.name, query)
-               self.closed = 0
-           elif _badQuery and self.conn.inTransaction:
-               raise NotSupportedError, \
-                     "DROP [TABLE|INDEX] within a transaction"
-           if not self.conn.inTransaction:
-               if _badQuery:
-                   pass # not in transaction so DROP TABLE/INDEX is ok.
-               else:
-                    self.conn._Connection__setupTransaction()
-
-       _nl = len(self.conn.notices)
-
-       try:
-           _qstr = self.__unicodeConvert(_qstr)
-           if len(parms) == 0:
-               # If there are no paramters, just execute the query.
-               self.res = self.conn.conn.query(_qstr)
-           else:
-               if len(parms) == 1 and \
-                  (type(parms[0]) in [DictType, ListType, TupleType] or \
-                                           isinstance(parms[0], PgResultSet)):
-                   parms = (self.__unicodeConvert(parms[0]),)
-                   parms = _quoteall(parms[0])
-               else:
-                   parms = self.__unicodeConvert(parms)
-                   parms = tuple(map(_quote, parms));
-               self.res = self.conn.conn.query(_qstr % parms)
-           self._rows_ = self.res.ntuples
-           self._idx_  = 0
-           self.__dict__['rowcount'] = -1 # New query - no fetch occured yet.
-           if type(self.res) is not PgResultType:
-               self.__dict__['rowcount'] = -1
-           else:
-               self.__dict__['oidValue'] =  self.res.oidValue
-               if self.res.resultType == RESULT_DQL:
-                   pass
-               elif self.res.resultType == RESULT_DML:
-                   self.__dict__['rowcount'] = self.res.cmdTuples
-               else:
-                   self.__dict__['rowcount'] = -1
-       except OperationalError, msg:
-           # Uh-oh.  A fatal error occurred.  This means the current trans-
-           # action has been aborted.  Try to recover to a sane state.
-           if self.conn.inTransaction:
-               _n = len(self.conn.notices)
-               self.conn.conn.query('ROLLBACK WORK')
-               if len(self.conn.notices) != _n:
-                   raise Warning, self.conn.notices.pop()
-               self.conn.__dict__["inTransaction"] = 0
-               self.conn._Connection__closeCursors()
-           raise OperationalError, msg
-       except InternalError, msg:
-           # An internal error occured.  Try to get to a sane state.
-           self.conn.__dict__["inTransaction"] = 0
-           self.conn._Connection__closeCursors_()
-           self.conn.close()
-           raise InternalError, msg
-
-       if len(self.conn.notices) != _nl:
-           _drop = self.conn.notices[-1]
-           if _drop.find('transaction is aborted') > 0:
-               raise Warning, self.conn.notices.pop()
-
-       if self.res.resultType == RESULT_DQL:
-           self.__makedesc__()
-       elif _qstr[:8] == 'DECLARE ':
-           # Ok -- we've created a cursor, we will pre-fetch the first row in
-           # order to make the description array.  Note: the first call to
-           # fetchXXX will return the pre-fetched record.
-           self.res = self.conn.conn.query('FETCH 1 FROM "%s"' % self.name)
-           self._rows_ = self.res.ntuples
-           self._idx_ = 0
-           self.__makedesc__()
-
-       if len(self.conn.notices) != _nl:
-           _drop = self.conn.notices[-1]
-           if _drop.find('transaction is aborted') > 0:
-               raise Warning, self.conn.notices.pop()
-           
-    def executemany(self, query, parm_sequence):
-       if self.closed:
-           raise InterfaceError, "executemany failed - the cursor is closed."
-
-       if self.conn is None:
-           raise Error, "connection is closed."
-
-       for _i in parm_sequence:
-           self.execute(query, _i)
-
-    def fetchone(self):
-       if self.closed:
-           raise InterfaceError, "fetchone failed - the cursor is closed."
-
-       if self.conn is None:
-           raise Error, "connection is closed."
-
-       if self.res is None:
-           raise Error, \
-                 "fetchone() failed - cursor does not contain a result."
-       elif self.res.resultType != RESULT_DQL:
-           if self.closed is None:
-               raise Error, \
-                     "fetchone() Failed - cursor does not contain any rows."
-
-       if self._idx_ < self._rows_:
-           pass        # Still data in result buffer, use it.
-       elif self.closed == 0:
-           _nl = len(self.conn.notices)
-           self.res = self.conn.conn.query('FETCH 1 FROM "%s"' % self.name)
-           self._rows_ = self.res.ntuples
-           self._idx_ = 0
-
-           if len(self.conn.notices) != _nl:
-               _drop = self.conn.notices[-1]
-               if _drop.find('transaction is aborted') > 0:
-                   raise Warning, self.conn.notices.pop()
-
-       return self.__fetchOneRow()
-
-    def fetchmany(self, sz=None):
-       if self.closed:
-           raise InterfaceError, "fetchmany failed - the cursor is closed."
-
-       if self.conn is None:
-           raise Error, "connection is closed."
-
-       if self.res is None:
-           raise Error, \
-                 "fetchmany() failed - cursor does not contain a result."
-       elif self.res.resultType != RESULT_DQL:
-           if self.close is None:
-               raise Error, \
-                     "fetchmany() Failed - cursor does not contain any rows."
-       
-       if sz is None:
-           sz = self.arraysize
-       else:
-           self.__dict__["arraysize"] = abs(sz)
-
-       if sz < 0:
-           return self.fetchall()
-           
-       _list = []
-
-       # While there are still results in the PgResult object, append them
-       # to the list of results.
-       while self._idx_ < self._rows_ and sz > 0:
-           _list.append(self.__fetchOneRow())
-           sz = sz - 1
-
-       # If still need more results to fullfill the request, fetch them from
-       # the PostgreSQL portal.
-       if self.closed == 0 and sz > 0:
-           _nl = len(self.conn.notices)
-           self.res = self.conn.conn.query('FETCH %d FROM "%s"' %
-                                           (sz, self.name))
-           self._rows_ = self.res.ntuples
-           self._idx_ = 0
-
-           if len(self.conn.notices) != _nl:
-               _drop = self.conn.notices[-1]
-               if _drop.find('transaction is aborted') > 0:
-                   raise Warning, self.conn.notices.pop()
-
-       return self.__fetchManyRows(sz, _list)
-
-    def fetchall(self):
-       if self.closed:
-           raise InterfaceError, "fetchall failed - the cursor is closed."
-
-       if self.conn is None:
-           raise Error, "connection is closed."
-
-       if self.res is None:
-           raise Error, \
-                  "fetchall() failed - cursor does not contain a result."
-       elif self.res.resultType != RESULT_DQL:
-           if self.closed is None:
-               raise Error, \
-                     "fetchall() Failed - cursor does not contain any rows."
-           
-       _list = []
-
-       # While there are still results in the PgResult object, append them
-       # to the list of results.
-       while self._idx_ < self._rows_:
-           _list.append(self.__fetchOneRow())
-
-       # Fetch the remaining results from the PostgreSQL portal.
-       if self.closed == 0:
-           _nl = len(self.conn.notices)
-           self.res = self.conn.conn.query('FETCH ALL FROM "%s"' % self.name)
-           self._rows_ = self.res.ntuples
-           self._idx_ = 0
-
-           if len(self.conn.notices) != _nl:
-               _drop = self.conn.notices[-1]
-               if _drop.find('transaction is aborted') > 0:
-                   raise Warning, self.conn.notices.pop()
-
-       return self.__fetchManyRows(self._rows_, _list)
-
-    def rewind(self):
-       if self.closed:
-           raise InterfaceError, "rewind failed - the cursor is closed."
-
-       if self.conn is None:
-           raise Error, "connection is closed."
-
-       if self.res is None:
-           raise Error, "rewind() failed - cursor does not contain a result."
-       elif self.res.resultType != RESULT_DQL:
-           if self.closed is None:
-               raise Error, \
-                         "rewind() Failed - cursor does not contain any rows."
-           
-       if self.closed == 0:
-           _nl = len(self.conn.notices)
-           self.res = self.conn.conn.query('MOVE BACKWARD ALL IN "%s"' %
-                                           self.name)
-           self._rows_ = 0
-           if len(self.conn.notices) != _nl:
-               _drop = self.conn.notices[-1]
-               if _drop.find('transaction is aborted') > 0:
-                   raise Warning, self.conn.notices.pop()
-
-       self.__dict__["rowcount"] = -1
-       self._idx_ = 0
-
-    def setinputsizes(self, sizes):
-       if self.closed:
-           raise InterfaceError, "setinputsize failed - the cursor is closed."
-
-    def setoutputsize(self, size, column=None):
-       if self.closed:
-           raise InterfaceError, "setoutputsize failed - the cursor is closed."
diff --git a/pgworksheet/pgw/RunSQL.py b/pgworksheet/pgw/RunSQL.py
deleted file mode 100644 (file)
index 77ecc30..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-# -*- coding: latin-1; -*-
-#
-# PgWorksheet - PostgreSQL Front End
-# http://pgworksheet.projects.postgresql.org/
-#
-# Copyright Â© 2004-2008 Henri Michelon & CML http://www.e-cml.org/
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details (read LICENSE.txt).
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# $Id
-#
-import string
-import pygtk
-import gtk
-
-import pgw
-
-
-class RunSQL:
-  """Execute the SQL buffer and fill the GtkNotebook with the results."""
-
-  def __init__(self, execute, txtSQL, tabResult, result):
-    self.execute = execute
-    self.txtSQL = txtSQL
-    self.lblResult = result
-    self.tabResult = tabResult
-    self.error_font = {}
-
-
-  def result(self, msg):
-    """update status bar text"""
-    self.lblResult.set_markup('<span foreground="#004400">' + msg + '</span>')
-
-
-  def str_limit(self, s, max = 20):
-    s = string.replace(s, '\\\\', '\\')
-    if (len(s) > (max + 3)):
-      return s[:max] + "..."
-    return s
-
-
-  def error(self, msg, title = None):
-    """update the error messages"""
-    if (title is None):
-      title = '<span foreground="#880000">' + _('Errors') + '</span>'
-    scroll = gtk.ScrolledWindow()
-    txt = gtk.TextView()
-    txt.get_buffer().set_text(unicode(msg, pgw.get_user_encoding()))
-    pgw.set_proportional(txt.get_buffer())
-    txt.set_editable(False)
-    scroll.add(txt)
-    scroll.show_all()
-    label = gtk.Label()
-    label.set_markup(title)
-    self.tabResult.append_page(scroll, label)
-
-
-  def add_treeview(self, title):
-    """Add a new tree view"""
-    scroll = gtk.ScrolledWindow()
-    tvw = gtk.TreeView()
-    scroll.add(tvw)
-    scroll.show()
-    label = gtk.Label(title)
-    self.tabResult.append_page(scroll, label)
-    return (tvw, label)
-    
-
-  def fill_treeview(self, sql, result):
-    """build the tree view columns and rows"""
-    sql = sql.strip()
-    treeview, label = self.add_treeview(self.str_limit(sql))
-    type_str = ""
-    cell = gtk.CellRendererText()
-    ncol = 0
-    for col in result.description:
-      column = gtk.TreeViewColumn(string.replace(col[0], "_", "__"))
-      column.pack_start(cell, True)
-      column.add_attribute(cell, 'text', ncol)
-      column.set_sort_column_id(ncol)
-      treeview.append_column(column)
-      ncol = ncol + 1
-      if (type_str == ""):
-        type_str = "str"
-      else:  
-        type_str = type_str + ",str"
-      pass
-      
-    # dynamically create the liststore
-    code = "liststore = gtk.ListStore(" + type_str + ")"
-    exec compile(code, "<string>", 'exec')
-
-    # fill the tree view
-    row = result.fetchone()
-    rows = 0
-    while ( row is not None ) :
-      c = 0
-      while c < len(row):
-        if (row[c] is None) and type(row) == list:
-          row[c] = '(null)'
-        c = c + 1
-      liststore.append(row)
-      row = result.fetchone()
-      rows = rows + 1
-    result.close()  
-    treeview.set_model(liststore)
-    treeview.set_reorderable(True)
-    treeview.columns_autosize()
-    treeview.show()
-    label.set_markup(label.get_text() + ' <span foreground="#555555">: ' + 
-                      str(rows) + "</span>")
-    return rows
-
-
-  def run(self):  
-    """Run the query and update the results"""
-    # clear the treeviews and the error text buffers
-    for child in self.tabResult.get_children():
-      self.tabResult.remove(child)
-    self.result(_("Please wait, executing the query and fetching the results..."))
-    # update the display
-    while (gtk.events_pending() == True):
-      gtk.main_iteration_do(False)
-
-    # execute the query
-    sqlbuffer=  self.txtSQL.get_buffer()
-    notices = []
-    try:
-      result = self.execute.execute(sqlbuffer)
-      rows = 0
-      if (isinstance(result, list)):
-        # multiple queries and multiple results...
-        parts = self.execute.split(sqlbuffer)
-        sqls = []
-        have_errors = 0
-        for sql in parts :
-          sql = string.strip(sql)
-          if (len(sql) > 0) :
-            sqls.append(sql)
-        for res in result:
-          sql = sqls.pop(0)
-          try:
-            if (res['cursor'].description is not None):
-              rows += self.fill_treeview(sql, res['cursor'])
-            else:  
-              rows += res['cursor'].rowcount
-            notices = res['notices']
-          except KeyError:    
-            try:
-              self.error(res['text'], "psql : " + self.str_limit(sql))
-            except KeyError:  
-              notices = res['notices']
-              self.error(res['error'],
-                          '<span foreground="#880000">' + _('Errors :') + '</span> ' + 
-                          self.str_limit(sql))
-              have_errors += 1
-        self.tabResult.set_current_page(0)
-        if (rows > 1):
-          res_str = _("%d results or affected rows") % rows
-        elif (rows == 1):
-          res_str = _("1 result or affected row")
-        else:
-          res_str = _("No result or no affected row")
-        if (have_errors > 1) :
-          res_str += ', <span foreground="#880000">' + \
-                    _('%d queries failed') % have_errors + '</span>'
-        elif (have_errors > 0) :  
-          res_str += ', <span foreground="#880000">' +  \
-                    _('1 query failed') + '</span>'
-        self.result(res_str)  
-      else: # one query
-        sql = sqlbuffer.get_text(sqlbuffer.get_start_iter(), 
-                                 sqlbuffer.get_end_iter())
-        try:
-          if (result is None):
-            self.result(_("No result"))
-          elif (result['cursor'].description is None):
-            # not a SELECT
-            rows = result['cursor'].rowcount
-            notices = result['notices']
-            if (rows > 1):
-              self.result(_("%d rows affected") % rows)
-            elif (rows == 1):
-              self.result(_("1 row affected"))
-            else:
-              self.result(_("No row affected"))
-          else:
-            # only one SELECT
-            rows = self.fill_treeview(sql, result['cursor'])
-            notices = result['notices']
-            if (rows > 1):
-              self.result(_("%d results") % rows)
-            elif (rows == 1):
-              self.result(_("1 result"))
-            else:
-              self.result(_("No result"))
-        except KeyError:
-          try:
-            self.error(result['text'], "psql : " + self.str_limit(sql))
-            self.result("")
-          except KeyError:  
-            self.error(result['error'])
-            self.result('<span foreground="#880000">' + _('query failed') + '</span>')
-            notices = result['notices']
-      buffer = self.txtSQL.get_buffer()
-      buffer.move_mark_by_name('selection_bound', buffer.get_start_iter());
-      buffer.move_mark_by_name('insert', buffer.get_end_iter());
-
-    except KeyError, errstr:
-      self.result('<span foreground="#880000">' + _('query failed') + '</span>')
-      self.error(str(errstr))
-
-    if (len(notices) > 0):
-      msg = ""
-      while len(notices):
-        msg += notices.pop()
-      self.error(msg, '<span foreground="#000088">'+ _("log") + '</span>')
-
-    # restore the focus 
-    self.txtSQL.grab_focus()
-
diff --git a/pgworksheet/pgw/Syntax.py b/pgworksheet/pgw/Syntax.py
deleted file mode 100644 (file)
index 21ae87a..0000000
+++ /dev/null
@@ -1,782 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: latin-1; -*-
-#
-# PgWorksheet - PostgreSQL Front End
-# http://pgworksheet.projects.postgresql.org/
-#
-# Copyright Â© 2004-2008 Henri Michelon & CML http://www.e-cml.org/
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details (read LICENSE.txt).
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# $Id: Syntax.py,v 1.30 2008/03/12 20:26:23 hmichelon Exp $
-#
-import gtk.gdk
-import pango
-import pgw
-import pgw.Lexical
-
-# built-in data types and extensions
-TYPES = [ 'BIGINT', 'INT8', 'BIGSERIAL', 'SERIAL8', 'BIT', 'VARYING',
-          'VARBIT', 'BOOL', 'BOOLEAN', 'BOX', 'BYTEA', 'CHARACTER', 'VARCHAR',
-          'CHAR', 'CIDR', 'CIRCLE', 'DATE', 'DOUBLE', 'PRECISION',
-          'INET', 'INTEGER', 'FLOAT8', 'INT', 'INT4', 'INTERVAL',
-          'LINE', 'LSEG', 'MACADDR', 'MONEY', 'NUMERIC', 'DECIMAL',
-          'PATH', 'POINT', 'POLYGON', 'REAL', 'FLOAT4', 'SMALLINT',
-          'INT2', 'SERIAL', 'SERIAL4', 'TEXT','TIME', 'TIMESTAMP',
-          'TIMETZ', 'TIMESTAMPTZ', 'WITHOUT', 'TIME', 'ZONE' 
-        ]
-
-# special constants
-SPECIALS = [ 'FALSE', 'NULL', 'TRUE', 'UNKNOWN', 'ALL', 'ANY', 'SOME' ]
-
-
-# named operators, constructs, conditionals and subqueries
-OPERATORS2 = [ 'OVERLAPS', 'AND', 'OR', 'NOT', 'BETWEEN', 'IS', 'ISNULL', 
-               'NOTNULL', 'CAST', 'LIKE', 'ILIKE', 'SIMILAR',
-               'EXISTS', 'IN',
-               'CASE', 'WHEN', 'THEN', 'ELSE', 'END',
-               'UNION', 'ARRAY',
-             ]  
-
-# SQL and PostgreSQL statements
-STATEMENTS = [ 'ABORT', 'ALTER', 'ANALYSE', 'BEGIN', 'CHECKPOINT', 'CLOSE', 
-               'CLUSTER', 'COMMENT', 'COMMIT', 'COPY', 'CREATE', 'DEALLOCATE', 
-               'DECLARE', 'DELETE', 'DROP', 'END', 'EXECUTE', 'EXPLAIN', 
-               'FETCH', 'GRANT', 'INSERT', 'LISTEN', 'LOAD', 'LOCK', 'MOVE', 
-               'NOTIFY', 'PREPARE', 'REINDEX', 'RELEASE', 'RESET', 'REVOKE', 
-               'ROLLBACK', 'SAVEPOINT', 'SELECT', 'SET', 'SHOW', 'START', 
-               'TRUNCATE', 'UNLISTEN', 'UPDATE', 'VACUUM' ]
-
-# built-in functions
-BUILTINS  = [ 
-              # MATH
-              'ABS', 'CBTR', 'CEIL', 'CEILING', 'DEGREES', 'EXP', 'FLOOR', 'LN',
-              'LOG', 'MOD', 'PI', 'POWER', 'RADIANS', 'RANDOM', 'ROUND', 
-              'SETSEED', 'SIGN', 'SQRT', 'TRUNC', 'WIDTH_BUCKET', 'ACOS', 
-              'ASIN', 'ATAN', 'ATAN2', 'COS', 'COT', 'SIN', 'TAN',
-              # STRING
-              'BIT_LENGTH', 'CHAR_LENGTH', 'CONVERT', 'LOWER', 'OCTET_LENGTH',
-              'OVERLAY', 'POSITION', 'SUBSTRING', 'TRIM', 'UPPER', 'ASCII',
-              'BTRIM', 'CHR', 'DECODE', 'ENCODE', 'INITCAP', 'LENGTH',
-              'LPAD', 'LTRIM', 'MD5', 'PG_CLIENT_ENCODING', 'QUOTE_IDENT',
-              'QUOTE_LITERAL', 'REPEAT', 'RPAD', 'RTRIM', 'SPLIT_PART',
-              'STRPOS', 'TO_ASCII', 'TO_HEX', 'TRANSLATE', 
-              # BSTRING
-              'GET_BYTE', 'SET_BYTE', 'GET_BIT', 'SET_BIT', 
-              # DATE
-              'TO_CHAR', 'TO_DATE', 'TO_TIMESTAMP', 'TO_NUMBER',
-              'AGE', 'DATE_PART', 'DATE_TRUNC', 'EXTRACT', 'ISFINITE',
-              'NOW', 'TIMEOFDAY',
-              # GEOMETRIC
-              'AREA', 'BOX_INTERSECT', 'CENTER', 'DIAMETER', 'HEIGHT',
-              'ISCLOSED', 'ISOPEN', 'LENGTH', 'NPOINTS', 'PCLOSE',
-              'POPEN', 'RADIUS', 'WIDTH', 'BOX', 'CIRCLE', 'LSEG',
-              'PATH', 'POINT', 'POLYGON', 
-              # NETWORK
-              'BROADCAST', 'HOST', 'MASKLEN', 'SET_MASKLEN',
-              'NETMASK', 'HOSTMASK', 'NETWORK', 'TEXT', 'ABBREV',
-              'FAMILY', 'TRUNC',
-              # SEQUENCES
-              'NEXTVAL', 'CURRVAL',
-              # CONDITIONAL
-              'COALESCE', 'NULLIF',
-              # ARRAY
-              'ARRAY_CAT', 'ARRAY_APPEND', 'ARRAY_PREPEND', 'ARRAY_DIMS',
-              'ARRAY_LOWER', 'ARRAY_UPPER', 'ARRAY_TO_STRING',
-              'STRING_TO_ARRAY'
-              # AGGREGATE
-              'AVG', 'BIT_AND', 'BIT_OR', 'BOOL_AND', 'BOOL_OR',
-              'COUNT', 'EVERY', 'MAX', 'MIN', 'STDDEV', 'SUM',
-              'VARIANCE'
-              # SETS
-              'GENERATE_SERIES',
-              # SYSTEM
-              'CURRENT_DATABASE', 'CURRENT_SCHEMA',
-              'INET_CLIENT_ADDR', 'INET_CLIENT_PORT',
-              'INET_SERVER_ADDR', 'INET_SERVER_PORT', 'VERSION',
-              'HAS_TABLE_PRIVILEGE', 'HAS_DATABASE_PRIVILEGE',
-              'HAS_FUNCTION_PRIVILEGE', 'HAS_LANGUAGE_PRIVILEGE',
-              'HAS_SCHEMA_PRIVILEGE', 'HAS_TABLESPACE_PRIVILEGE'
-              'PG_TABLE_IS_VISIBLE', 'PG_TYPE_IS_VISIBLE',
-              'PG_FUNCTION_IS_VISIBLE', 'PG_OPERATOR_IS_VISIBLE',
-              'PG_OPCLASS_IS_VISIBLE', 'PG_CONVERSION_IS_VISIBLE',
-              'FORMAT_TYPE', 'PG_GET_VIEWDEF', 'PG_GET_RULEGET',
-              'PG_GET_INDEXDEF', 'PG_GET_TRIGGERDEF',
-              'PG_GET_CONSTRAINTDEF', 'PG_GET_EXPR', 'PG_GET_USERBYID',
-              'PG_GET_SERIAL_SEQUENCE', 'PG_TABLESPACE_DATABASES',
-              'OBJ_DESCRIPITION',
-              # SYSTEM ADMIN
-              'CURRENT_SETTINGS', 'SET_CONFIG', 'PG_CANCEL_BACKEND',
-              'PG_START_BACKUP', 'PG_STOP_BACKUP',
-
-            ]
-
-# built-in functions that can be used without ()
-# or conditional expressions
-BUILTINS2 = [ # DATE
-              'CURRENT_DATE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP',
-              'LOCALTIME', 'LOCALTIMESTAMP',
-              # SYSTEM
-              'CURRENT_USER', 'SESSION_USER', 'USER',
-            ]
-
-
-"""
-# PL/PgSQL keywords
-PLPGSQL = [ # structure
-            'DECLARE', 'BEGIN', 'END',
-            # declarations
-            'RECORD', 'DEFAULT', 'CONSTANT', 'ALIAS', 'FOR', 'TYPE', 'ROWTYPE',
-            'RENAME', 'TO',
-            # Statements
-            'FOUND', 'PERFORM', 'GET', 'DIAGNOSTICS', 
-            # Control Structures
-            'RETURN', 'NEXT', 'IF', 'THEN', 'ELSE', 'END', 'ELSIF', 'LOOP',
-            'EXIT', 'WHILE', 'REVERSE', 'IN', 'EXCEPTION', 'WHEN',
-            # Cursors
-            'CURSOR', 'OPEN', 'EXECUTE', 'FETCH', 'INTO', 'CLOSE',
-            # Errors
-            'RAISE', 'DEBUG', 'LOG', 'INFO', 'NOTICE', 'WARNING', 'EXCEPTION',
-            # Trigger Procedures
-            'NEW', 'OLD', 'TG_NAME', 'TG_WHEN', 'TG_LEVEL', 'TG_OP',
-            'TG_RELID', 'TG_RELNAME', 'TG_NARGS', 'TG_ARGV',
-          ]  
-"""
-
-# keywords for each statement
-KEYWORDS = { 'ABORT'    : [ 'WORK', 'TRANSACTION' ],
-             'ALTER'    : { 'AGGREGATE'   : [ [ 'RENAME', 'TO' ], 
-                                              [ 'OWNER', 'TO' ]
-                                            ],
-                            'CONVERSION'  : [ [ 'RENAME', 'TO' ],
-                                              [ 'OWNER', 'TO' ]
-                                            ],
-                            'DATABASE'    : [ 'SET', 'TO', 'DEFAULT',
-                                              'RESET', [ 'RENAME', 'TO' ],
-                                              [ 'OWNER', 'TO' ]
-                                            ],
-                            'DOMAIN'      : [ [ 'SET', 'DEFAULT' ],
-                                              [ 'DROP', 'DEFAULT' ],
-                                              'ADD',
-                                              [ 'DROP', 'CONSTRAINT' ],
-                                              'RESTRICT', 'CASCADE',
-                                              [ 'OWNER', 'TO' ]
-                                            ],
-                            'FUNCTION'    : [ [ 'RENAME', 'TO' ],
-                                              [ 'OWNER', 'TO' ]
-                                            ],
-                            'GROUP'       : [ [ 'ADD', 'USER' ],
-                                              [ 'DROP', 'USER' ],
-                                              [ 'RENAME', 'TO' ]
-                                            ],
-                            'INDEX'       : [ [ 'RENAME', 'TO' ],
-                                              [ 'OWNER', 'TO' ],
-                                              [ 'SET', 'TABLESPACE' ]
-                                            ],
-                            'LANGUAGE'    : [ [ 'RENAME', 'TO' ] ],
-                            'OPERATOR'    : [ 'NONE', [ 'OWNER', 'TO' ], 
-                                              'CLASS', 'USING'
-                                            ],
-                            'SCHEMA'      : [ [ 'RENAME', 'TO' ],
-                                              [ 'OWNER', 'TO' ]
-                                            ],
-                            'SEQUENCE'    : [ [ 'INCREMENT', 'BY' ], 
-                                              'MINVALUE', 'MAXVALUE',
-                                              [ 'RESTART', 'WITH' ], 'CACHE',
-                                              'NO', 'CYCLE'
-                                            ],
-                            'TABLE'       : [ 'ONLY', [ 'RENAME', 'COLUMN' ],
-                                               [ 'RENAME', 'TO' ], 'TO',
-                                               [ 'ADD', 'COLUMN' ],
-                                               [ 'DROP', 'COLUMN' ], 'RESTRICT',
-                                               'CASCADE', 'TYPE', 'USING',
-                                               [ 'ALTER', 'COLUMN' ], 
-                                               [ 'SET', 'DEFAULT' ],
-                                               [ 'DROP', 'DEFAULT' ],
-                                               'SET', 'DROP',
-                                               [ 'SET', 'STATISTICS' ],
-                                               [ 'SET', 'STORAGE' ], 'PLAIN', 
-                                               'EXTERNAL', 'EXTERNAL', 'MAIN',
-                                               [ 'DROP', 'CONSTRAINT' ],
-                                               [ 'CLUSTER', 'ON' ],
-                                               [ 'SET', 'WITHOUT', 'CLUSTER' ],
-                                               [ 'SET', 'WITHOUT', 'OIDS' ],
-                                               [ 'OWNER', 'TO' ],
-                                               [ 'SET', 'TABLESPACE' ],
-                                               'CHECK', 
-                                               [ 'FOREIGN', 'KEY' ], 'CASCADE',
-                                               [ 'PRIMARY', 'KEY' ],
-                                               [ 'ON', 'DELETE' ],
-                                               [ 'ON', 'UPDATE' ], 'REFERENCES',
-                                             ],
-                            'TABLESPACE'  : [ [ 'RENAME', 'TO' ],
-                                              [ 'OWNER', 'TO' ]
-                                            ],
-                            'TRIGGER'     : [ 'ON', [ 'RENAME', 'TO' ] ],
-                            'TYPE'        : [ [ 'OWNER', 'TO' ] ],
-                            'USER'        : [ 'WITH', 'CREATEDB', 'NOCREATEDB',
-                                              'CREATEUSER', 'NOCREATEUSER',
-                                              'ENCRYPTED', 'UNENCRYPTED',
-                                              'PASSWORD', [ 'VALID', 'UNTIL' ],
-                                              [ 'RENAME', 'TO' ], 'SET',
-                                              'TO', 'DEFAULT', 'RESET'
-                                            ],
-                          },
-             'ANALYZE'  : [ 'VERBOSE' ],
-             'BEGIN'    : [ 'WORK', 'TRANSACTION', [ 'ISOLATION', 'LEVEL' ],
-                            'SERIALIZABLE', [ 'REPEATABLE', 'READ' ],
-                            [ 'READ', 'COMMITTED' ], [ 'READ', 'UNCOMMITTED' ],
-                            [ 'READ', 'WRITE' ], [ 'READ', 'ONLY' ]
-                          ],
-             'CHECKPOINT' : [],
-             'CLOSE'    : [],
-             'CLUSTER'  : [ 'ON' ],
-             'COMMENT'  : { 'ON' : [ 'TABLE', 'COLUMN', 'AGGREGATE', 'CAST',
-                                     'AS', 'CONSTRAINT', 'ON', 'CONVERSION',
-                                     'DATABASE', 'DOMAIN', 'FUNCTION', 'INDEX',
-                                     [ 'LARGE', 'OBJECT' ], 'OPERATOR',
-                                     [ 'OPERATOR', 'CLASS' ], 'USING', 
-                                     'PROCEDURAL', 'LANGUAGE', 'RULE',
-                                     'SCHEMA', 'SEQUENCE', 'TRIGGER',
-                                     'TYPE', 'VIEW', 'IS'
-                                   ]
-                          },         
-             'COMMIT'   : [ 'WORK', 'TRANSACTION' ],
-             'COPY'     : [ 'FROM', 'STDIN', 'WITH', 'BINARY', 'OIDS',
-                            'DELIMITER', 'CSV', 'AS', 'ESCAPE'
-                            'FORCE', 'TO', 'STDOUT', 'QUOTE'
-                          ],  
-             'CREATE'   : { 'AGGREGATE'   : [ 'BASETYPE', 'SFUNC', 'STYPE',
-                                              'FINALFUNC', 'INITCOND' ],
-                            'CAST'        : [ [ 'WITH', 'FUNCTION' ],
-                                              [ 'AS', 'ASSIGNMENT' ],
-                                              [ 'AS', 'IMPLICIT' ],
-                                              [ 'WITHOUT', 'FUNCTION']
-                                            ],
-                            'CONSTRAINT'  : [ 'TRIGGER', 'AFTER', 'ON',
-                                              [ 'FOR', 'EACH', 'ROW', 'EXECUTE'
-                                                'PROCEDURE' ]
-                                            ],
-                            'CONVERSION'  : [ 'FOR', 'TO', 'FROM' ],
-                            'DEFAULT'     : [ 'CONVERSION', 'FOR', 
-                                              'TO', 'FROM' ],
-                            'DATABASE'    : [ 'WITH', 'OWNER', 'TEMPLATE',
-                                              'ENCODING', 'TABLESPACE', 
-                                              'DEFAULT' ],
-                            'DOMAIN'      : [ 'AS', 'DEFAULT', 'CONSTRAINT',
-                                              'CHECK'
-                                            ],
-                            'OR'          : [ 'REPLACE', 'FUNCTION',
-                                              'RETURNS', 'LANGUAGE', 'AS',
-                                              'IMMUTABLE', 'STABLE',
-                                              'VOLATILE', [ 'CALLED', 'ON',
-                                              'NULL', 'INPUT' ], [ 'RETURNS',
-                                              'NULL', 'ON', 'NULL', 'INPUT' ],
-                                              'STRICT', 'EXTERNAL',
-                                              [ 'SECURITY', 'INVOKER' ],
-                                              [ 'SECURITY', 'DEFINER' ], 'WITH',
-                                              # XXX: for RULE
-                                              'RULE',
-                                              'AS', 'ON', 'TO', 'WHERE',
-                                              'DO', 'ALSO', 'INSTEAD', 
-                                              'NOTHING',
-                                              'VIEW'
-                                            ],  
-                            'FUNCTION'    : [ 'RETURNS', 'LANGUAGE', 'AS',
-                                              'IMMUTABLE', 'STABLE',
-                                              'VOLATILE', [ 'CALLED', 'ON',
-                                              'NULL', 'INPUT' ], [ 'RETURNS',
-                                              'NULL', 'ON', 'NULL', 'INPUT' ],
-                                              'STRICT', 'EXTERNAL',
-                                              [ 'SECURITY', 'INVOKER' ],
-                                              [ 'SECURITY', 'DEFINER' ], 'WITH'
-                                            ],
-                            'GROUP'       : [ 'WITH', 'SYSID', 'USER' ],
-                            'UNIQUE'      : [ 'ON', 'USING', 'TABLESPACE',
-                                              'WHERE', 'INDEX' ],
-                            'INDEX'       : [ 'ON', 'USING', 'TABLESPACE',
-                                              'WHERE', 'RTREE', 'HASH' ],
-                            'LANGUAGE'    : [ 'HANDLER', 'VALIDATOR' ],
-                            'PROCEDURAL'  : [ 'HANDLER', 'VALIDATOR', 
-                                              'LANGUAGE' ],
-                            'TRUSTED'     : [ 'HANDLER', 'VALIDATOR', 
-                                              'LANGUAGE' ],
-                            'OPERATOR'    : [ 'PROCEDURE', 'LEFTARG', 
-                                              'RIGHTARG', 'COMMUTATOR',
-                                              'NEGATOR', 'RESTRICT',
-                                              'JOIN', 'HASHES', 'MERGES',
-                                              'SORT1', 'SORT2', 'LTCMP',
-                                              'GTCMP',
-                                              'CLASS', 'DEFAULT',
-                                              [ 'FOR', 'TYPE' ], 'USING',
-                                              'AS', 'OPERATOR', 'RECHECK',
-                                              'FUNCTION', 'STORAGE' ],
-                            'RULE'        : [ 'AS', 'ON', 'TO', 'WHERE',
-                                              'DO', 'ALSO', 'INSTEAD', 
-                                              'NOTHING' ],
-                            'SCHEMA'      : [ 'AUTHORIZATION' ],
-                            'SEQUENCE'    : [ 'INCREMENT', 'BY', 'MINVALUE',
-                                              'NO', 'MAXVALUE', [ 'START', 
-                                              'WITH' ], 'CACHE', 'CYCLE' ],
-                            'TEMPORARY'    : [ 'SEQUENCE',
-                                               'INCREMENT', 'BY', 'MINVALUE',
-                                              'NO', 'MAXVALUE', [ 'START', 
-                                              'WITH' ], 'CACHE', 'CYCLE',
-                                              # CREATE TABLE
-                                              'TABLE',
-                                              'DEFAULT', 'INCLUDING',
-                                              'EXCLUDING', 'DEFAULTS', 
-                                              'INHERITS', 'WITH',
-                                              'WITHOUT', 'OIDS',
-                                              [ 'ON', 'COMMIT' ], 
-                                              [ 'PRESERVE', 'ROWS' ],
-                                              [ 'DELETE', 'ROWS' ], 'DROP',
-                                              'TABLESPACE', 'CONSTRAINT',
-                                              'UNIQUE',
-                                              [ 'USING', 'INDEX', 'TABLESPACE'],
-                                              [ 'PRIMARY', 'KEY' ], 'CHECK',
-                                              'REFERENCES', [ 'MATCH', 'FULL' ],
-                                              [ 'MATCH', 'PARTIAL' ], 
-                                              [ 'MATCH', 'SIMPLE' ],
-                                              [ 'ON', 'DELETE' ], 
-                                              [ 'ON', 'UPDATE' ], 'DEFERRABLE', 
-                                              [ 'INITIALLY', 'DEFERRED' ],
-                                              [ 'INITIALLY', 'IMMEDIATE' ],
-                                              [ 'FOREIGN', 'KEY' ],
-                                               'CHECK', 
-                                            ],  
-                            'TEMP'        : [ 'SEQUENCE',
-                                               'INCREMENT', 'BY', 'MINVALUE',
-                                              'NO', 'MAXVALUE', [ 'START', 
-                                              'WITH' ], 'CACHE', 'CYCLE',
-                                              # CREATE TABLE
-                                              'TABLE',
-                                              'DEFAULT', 'INCLUDING',
-                                              'EXCLUDING', 'DEFAULTS', 
-                                              'INHERITS', 'WITH', 'OIDS',
-                                              'WITHOUT', 
-                                              [ 'ON', 'COMMIT' ], 
-                                              [ 'PRESERVE', 'ROWS' ],
-                                              [ 'DELETE', 'ROWS' ], 'DROP',
-                                              'TABLESPACE', 'CONSTRAINT',
-                                              'UNIQUE',
-                                              [ 'USING', 'INDEX', 'TABLESPACE'],
-                                              [ 'PRIMARY', 'KEY' ], 'CHECK',
-                                              'REFERENCES', [ 'MATCH', 'FULL' ],
-                                              [ 'MATCH', 'PARTIAL' ], 
-                                              [ 'MATCH', 'SIMPLE' ],
-                                              [ 'ON', 'DELETE' ], 
-                                              [ 'ON', 'UPDATE' ], 'DEFERRABLE', 
-                                              [ 'INITIALLY', 'DEFERRED' ],
-                                              [ 'INITIALLY', 'IMMEDIATE' ],
-                                              [ 'FOREIGN', 'KEY' ],
-                                               'CHECK', 
-                                            ],  
-                            'LOCAL'       : [ 'TABLE',
-                                              'DEFAULT', 'INCLUDING',
-                                              'EXCLUDING', 'DEFAULTS', 
-                                              'INHERITS', 'WITH',
-                                              'WITHOUT', 'OIDS',
-                                              [ 'ON', 'COMMIT' ], 
-                                              [ 'PRESERVE', 'ROWS' ],
-                                              [ 'DELETE', 'ROWS' ], 'DROP',
-                                              'TABLESPACE', 'CONSTRAINT',
-                                              'UNIQUE',
-                                              [ 'USING', 'INDEX', 'TABLESPACE'],
-                                              [ 'PRIMARY', 'KEY' ], 'CHECK',
-                                              'REFERENCES', [ 'MATCH', 'FULL' ],
-                                              [ 'MATCH', 'PARTIAL' ], 
-                                              [ 'MATCH', 'SIMPLE' ],
-                                              [ 'ON', 'DELETE' ], 
-                                              [ 'ON', 'UPDATE' ], 'DEFERRABLE', 
-                                              [ 'INITIALLY', 'DEFERRED' ],
-                                              [ 'INITIALLY', 'IMMEDIATE' ],
-                                              [ 'FOREIGN', 'KEY' ],
-                                               'CHECK',
-                                            ],  
-                            'GLOBAL'      : [ 'TABLE',
-                                              'DEFAULT', 'INCLUDING',
-                                              'EXCLUDING', 'DEFAULTS', 
-                                              'INHERITS', 'WITH', 'OIDS',
-                                              'WITHOUT',
-                                              [ 'ON', 'COMMIT' ], 
-                                              [ 'PRESERVE', 'ROWS' ],
-                                              [ 'DELETE', 'ROWS' ], 'DROP',
-                                              'TABLESPACE', 'CONSTRAINT',
-                                              'UNIQUE',
-                                              [ 'USING', 'INDEX', 'TABLESPACE'],
-                                              [ 'PRIMARY', 'KEY' ], 'CHECK',
-                                              'REFERENCES', [ 'MATCH', 'FULL' ],
-                                              [ 'MATCH', 'PARTIAL' ], 
-                                              [ 'MATCH', 'SIMPLE' ],
-                                              [ 'ON', 'DELETE' ], 
-                                              [ 'ON', 'UPDATE' ], 'DEFERRABLE', 
-                                              [ 'INITIALLY', 'DEFERRED' ],
-                                              [ 'INITIALLY', 'IMMEDIATE' ],
-                                              [ 'FOREIGN', 'KEY' ],
-                                               'CHECK',
-                                            ],  
-                            'TABLE'       : [ 'DEFAULT', 'INCLUDING',
-                                              'EXCLUDING', 'DEFAULTS', 
-                                              'INHERITS', 'WITH', 'OIDS',
-                                              'WITHOUT',
-                                              [ 'ON', 'COMMIT' ], 
-                                              [ 'PRESERVE', 'ROWS' ],
-                                              [ 'DELETE', 'ROWS' ], 'DROP',
-                                              'TABLESPACE', 'CONSTRAINT',
-                                              'UNIQUE',
-                                              [ 'USING', 'INDEX', 'TABLESPACE'],
-                                              [ 'PRIMARY', 'KEY' ], 'CHECK',
-                                              'REFERENCES', [ 'MATCH', 'FULL' ],
-                                              [ 'MATCH', 'PARTIAL' ], 
-                                              [ 'MATCH', 'SIMPLE' ],
-                                              [ 'ON', 'DELETE' ], 
-                                              [ 'ON', 'UPDATE' ], 'DEFERRABLE', 
-                                              'INITIALLY', 'DEFERRED',
-                                              'IMMEDIATE', 'RESTRICT',
-                                              [ 'FOREIGN', 'KEY' ], 'CASCADE'
-                                               'CHECK',
-                                            ],
-                            'TABLESPACE'  : [ 'OWNER', 'LOCATION' ],
-                            'TRIGGER'     : [ 'BEFORE', 'AFTER', 'OR', 'ON',
-                                              'FOR', 'EACH', 'ROW', 'STATEMENT',
-                                              [ 'EXECUTE', 'PROCEDURE' ]
-                                            ],  
-                            'TYPE'        : [ 'AS', 'INPUT', 'OUTPUT', 
-                                              'RECEIVE', 'SEND', 'ANALYZE',
-                                              'INTERNALLENGTH', 'VARIABLE',
-                                              'PASSEDBYVALUE', 'ALIGNMENT',
-                                              'STORAGE', 'DEFAULT',
-                                              'ELEMENT', 'DELIMITER' ],  
-                            'USER'        : [ 'WITH', 'SYSID', 'CREATEDB',
-                                              'NOCREATEDB', 'CREATEUSER',
-                                              'NOCREATEUSER', [ 'IN', 'GROUP' ],
-                                              'ENCRYPTED', 'UNENCRYPTED',
-                                              'PASSWORD', [ 'VALID', 'UNTIL' ]
-                                            ],  
-                            'VIEW'        : [ 'AS' ,
-                                              # select
-                                              'SELECT', 'DISTINCT', 'ON',
-                                              'AS', 'FROM', 'WHERE', 
-                                              [ 'GROUP', 'BY' ], 'HAVING', 
-                                              'UNION', 'INTERSECT', 'EXCEPT', 
-                                              [ 'ORDER', 'BY' ], 'ASC', 
-                                              'DESC', 'USING', 'LIMIT', 
-                                              'OFFSET', [ 'FOR', 'UPDATE', 
-                                              'OF' ], 'ONLY', 'NATURAL', 
-                                              'USING', 'INNER', 'LEFT', 'OUTER',
-                                              'RIGHT', 'FULL', 'JOIN', 'CROSS',
-                                              'INTO' ],
-                          },
-             'DEALLOCATE': [ 'PREPARE' ],
-             'DECLARE'  : [ 'BINARY', 'INSENSITIVE', 'NO', 'SCROLL',
-                            'CURSOR', 'WITH', 'WITHOUT', 'HOLD', 'FOR',
-                            [ 'READ', 'ONLY' ], 'UPDATE', 'OF' ],
-             'DELETE'   : { 'FROM'        : [ 'ONLY', 'WHERE' ] },
-             'DROP'     : { 'AGGREGATE'   : [ 'CASCADE', 'RESTRICT' ],
-                            'CAST'        : [ 'AS', 'CASCADE', 'RESTRICT' ],
-                            'CONVERSION'  : [ 'CASCADE', 'RESTRICT' ],
-                            'DATABASE'    : [],
-                            'DOMAIN'      : [ 'CASCADE', 'RESTRICT' ],
-                            'FUNCTION'    : [ 'CASCADE', 'RESTRICT' ],
-                            'GROUP'       : [],
-                            'INDEX'       : [ 'CASCADE', 'RESTRICT' ],
-                            'LANGUAGE'    : [ 'CASCADE', 'RESTRICT' ],
-                            'PROCEDURAL'  : ['LANGUAGE', 'CASCADE', 'RESTRICT'],
-                            'OPERATOR'    : [ 'NONE', 'CASCADE', 'RESTRICT',
-                                              'CLASS', 'USING' ],
-                            'RULE'        : [ 'ON', 'CASCADE', 'RESTRICT' ],
-                            'SCHEMA'      : [ 'CASCADE', 'RESTRICT' ],
-                            'SEQUENCE'    : [ 'CASCADE', 'RESTRICT' ],
-                            'TABLE'       : [ 'CASCADE', 'RESTRICT' ],
-                            'TABLESPACE'  : [],
-                            'TRIGGER'     : [ 'ON', 'CASCADE', 'RESTRICT' ],
-                            'TYPE'        : [ 'CASCADE', 'RESTRICT' ],
-                            'USER'        : [],
-                            'VIEW'        : [ 'CASCADE', 'RESTRICT' ],
-                          },
-             'END'      : [ 'WORK', 'TRANSACTION' ],
-             'EXECUTE'  : [],
-             'EXPLAIN'  : [ 'ANALYZE', 'VERBOSE' ],
-             'FETCH'    : [ 'FROM', 'IN', 'NEXT', 'PRIOR', 'FIRST', 'LAST',
-                            'ABSOLUTE', 'RELATIVE', 'FORWARD',
-                            'BACKWARD' ],
-             'GRANT'    : [ 'SELECT', 'INSERT', 'UPDATE', 'DELETE', 'RULE',
-                            'REFERENCES', 'TRIGGER', 'PRIVILEGES',
-                            'ON', 'TABLE', 'TO', 'GROUP', 'PUBLIC',
-                            [ 'WITH', 'GRANT', 'OPTION' ],
-                            'CREATE', 'TEMPORARY', 'TEMP', 'PRIVILEGES',
-                            'DATABASE', 'EXECUTE', 'FUNCTION', 'USAGE',
-                            'LANGUAGE', 'SCHEMA', 'TABLESPACE' ],
-             'INSERT'   : { 'INTO' : [ 'DEFAULT', 'VALUES',
-                                       'SELECT', 'DISTINCT', 'ON', 'AS',
-                                       'FROM', 'WHERE', [ 'GROUP', 'BY' ], 
-                                       'HAVING', 'UNION', 'INTERSECT', 'EXCEPT',
-                                       [ 'ORDER', 'BY' ],
-                                       'ASC', 'DESC', 'USING', 'LIMIT',
-                                       'OFFSET', [ 'FOR', 'UPDATE', 'OF' ], 
-                                       'ONLY', 'NATURAL', 'USING', 'INNER', 
-                                       'LEFT', 'OUTER', 'RIGHT', 'FULL', 
-                                       'JOIN', 'CROSS', 'INTO',
-                                     ]
-                          },           
-             'LISTEN'   : [],
-             'LOAD'     : [],
-             'LOCK'     : [ 'TABLE', 'IN', 'MODE', 'NOWAIT',
-                            [ 'ACCESS', 'SHARE' ], [ 'ROW', 'SHARE' ],
-                            [ 'ROW', 'EXCLUSIVE' ], 
-                            [ 'SHARE', 'UPDATE', 'EXCLUSIVE' ],
-                            'SHARE', [ 'SHARE', 'ROW', 'EXCLUSIVE' ],
-                            'EXCLUSIVE', [ 'ACCESS', 'EXCLUSIVE' ] ],
-             'MOVE'     : [ 'FROM', 'IN' ],
-             'NOTIFY'   : [],
-             'PREPARE'  : [ 'AS' ],
-             'REINDEX'  : [ 'DATABASE', 'TABLE', 'TABLE', 'FORCE' ],
-             'RELEASE'  : [ 'SAVEPOINT' ],
-             'RESET'    : [ ],
-             'REVOKE'   : [ [ 'GRANT', 'OPTION', 'FOR' ], 'SELECT', 'INSERT',
-                            'UPDATE', 'DELETE', 'RULE', 'REFERENCES',
-                            'TRIGGER', 'PRIVILEGES', 'ON', 'TABLE',
-                            'FROM', 'GROUP', 'PUBLIC', 'CASCADE', 'RESTRICT',
-                            'CREATE', 'TEMPORARY', 'TEMP', 'EXECUTE',
-                            'USAGE', 'SCHEMA', 'LANGUAGE', 'TABLESPACE' ],
-             'ROLLBACK' : [ 'WORK', 'TRANSACTION', 'TO', 'SAVEPOINT' ],
-             'SAVEPOINT': [],
-
-             'SELECT'   : [ 'SELECT', 'INTO', 'DISTINCT', 'ON', 'AS', 'FROM',
-                            'WHERE', [ 'GROUP', 'BY' ], 'HAVING', 'UNION',
-                            'INTERSECT', 'EXCEPT', [ 'ORDER', 'BY' ],
-                            'ASC', 'DESC', 'USING', 'LIMIT', 'OFFSET',
-                            [ 'FOR', 'UPDATE', 'OF' ], 'ONLY', 'NATURAL',
-                            'USING', 'INNER', 'LEFT', 'OUTER', 'RIGHT', 'FULL',
-                            'JOIN', 'CROSS', 'INTO' ],
-             'SET'      : [ 'SESSION', 'LOCAL', 'TO', 'DEFAULT', 'LOCAL',
-                            [ 'TIME', 'ZONE' ], 'CONSTRAINTS', 
-                            'DEFERRED', 'IMMEDIATE', 'AUTHORIZATION',
-                            'TRANSACTION', 'CHARACTERISTICS',
-                            [ 'ISOLATION', 'LEVEL' ], 'SERIALIZABLE',
-                            [ 'REPEATABLE', 'READ' ], [ 'READ', 'COMMITTED' ],
-                            [ 'READ', 'UNCOMMITTED' ], [ 'READ', 'WRITE' ],
-                            [ 'READ', 'ONLY' ]
-                          ],
-             'SHOW'     : [ ],
-             'START'    : { 'TRANSACTION' : [ [ 'ISOLATION', 'LEVEL' ], 
-                                              'SERIALIZABLE', 
-                                              [ 'REPEATABLE', 'READ' ], 
-                                              [ 'READ', 'COMMITTED' ], 
-                                              [ 'READ', 'UNCOMMITTED' ], 
-                                              [ 'READ', 'WRITE' ], 
-                                              [ 'READ', 'ONLY' ] 
-                                            ],
-                          },
-             'TRUNCATE' : [ 'TABLE' ],
-             'UNLISTEN' : [],
-             'UPDATE'   : [ 'ONLY', 'SET', 'DEFAULT', 'FROM', 'WHERE' ],
-             'VACUUM'   : [ 'FULL', 'FREEZE', 'VERBOSE', 'ANALYSE' ]
-           }
-      
-
-class Syntax:
-  """Syntax highlight"""
-
-  def __init__(self, buffer):
-    self.lexical = pgw.Lexical.Lexical()
-    self.buffer = buffer
-    self.last = None
-    # default colors
-    self.tag = {}
-    self.tag['font'] = self.buffer.create_tag("font")
-    if (pgw.mswindows()):
-      self.tag['font'].set_property('font', 'Courier New 10')
-    else:
-      self.tag['font'].set_property('family', 'monospace')
-    self.tag['function'] = self.buffer.create_tag("function")
-    self.tag['function'].set_property('foreground', '#009999')
-    self.tag['dollarquote'] = self.buffer.create_tag("dollarquote")
-    self.tag['dollarquote'].set_property('foreground', '#000000')
-    self.tag['identifier'] = self.buffer.create_tag("identifier")
-    self.tag['identifier'].set_property('foreground', '#000000')
-    self.tag['keyword'] = self.buffer.create_tag("keyword")
-    self.tag['keyword'].set_property('foreground', '#0000FF')
-    self.tag['type'] = self.buffer.create_tag("type")
-    self.tag['type'].set_property('foreground', '#009900')
-    self.tag['string'] = self.buffer.create_tag("string")
-    self.tag['string'].set_property('foreground', '#F700BF')
-    self.tag['numeric_constant'] = self.buffer.create_tag("numeric_constant")
-    self.tag['numeric_constant'].set_property('foreground', '#c53838')
-    self.tag['special'] = self.buffer.create_tag("special")
-    self.tag['special'].set_property('foreground', '#c53838')
-    self.tag['comment'] = self.buffer.create_tag("comment")
-    self.tag['comment'].set_property('foreground', '#999999')
-    self.tag['comment2'] = self.buffer.create_tag("comment2")
-    self.tag['comment2'].set_property('style', pango.STYLE_ITALIC)
-    self.tag['operator'] = self.buffer.create_tag("operator")
-    self.tag['operator'].set_property('foreground', '#555555')
-    self.tag['psql'] = self.buffer.create_tag("psql")
-    self.tag['psql'].set_property('background', '#d0d4df')
-
-
-  def start_of_prev_statement(self, iter):
-    """Find the first character of a statement"""
-    if (self.last is not None):
-      self.found = None
-      for token in self.last:
-        if (token.start_iter.compare(iter) >= 0):
-          if (self.found is None):
-            break
-          return self.found.start_iter
-        if (token.value == ';'):
-          self.found = token
-      if (self.found):
-        return self.found.start_iter
-    return iter.get_buffer().get_start_iter()
-
-
-  def start_of_next_statement(self, iter):
-    """Find the last character of a statement"""
-    if (self.last is not None):
-      self.found = None
-      for token in reversed(self.last):
-        if (token.end_iter.compare(iter) <= 0):
-          if (self.found is None):
-            break
-          return self.found.end_iter
-        if (token.value == ';'):
-          self.found = token
-      if (self.found):
-        return self.found.end_iter
-    return iter.get_buffer().get_end_iter()
-
-
-  def text_inserted(self, buffer, iter, text, length):
-    """Called by Gtk when text is inserted in the buffer:
-      prepare 'start' and 'end' for text_changed()"""
-    self.start = self.start_of_prev_statement(iter.copy()).get_offset()
-    self.end = self.start_of_next_statement(iter.copy()).get_offset() + length
-
-    
-  def text_deleted(self, buffer, start, end):
-    """Called by Gtk when text is deleted from the buffer:
-      prepare 'start' and 'end' for text_changed()"""
-    self.start = self.start_of_prev_statement(start.copy()).get_offset()
-    self.end = self.start_of_next_statement(end.copy()).get_offset()
-    
-
-  def text_changed(self, buffer):
-    """Called by Gtk when (after) text is deleted or inserted
-    in the buffer. Uses 'start' and 'end' prepared in text_inserted
-    and text_deleted then run the analyse"""
-    start = self.buffer.get_iter_at_offset(self.start)
-    end = self.buffer.get_iter_at_offset(self.end)
-    self.analyse(start, end)
-
-
-  def refresh(self):
-    """Used when you want to manually refresh the syntax highlight
-    of the whole buffer"""
-    start = self.buffer.get_start_iter()
-    end = self.buffer.get_end_iter()
-    self.analyse(start, end)
-
-    
-  def analyse(self, start, end):
-    """Run the lexical and syntaxical analysers then
-    apply the syntax highlight to the buffer"""
-    self.tokens = self.lexical.analyse(self.buffer, start, end)
-    self.syntaxical_analyser()
-    self.buffer.remove_all_tags(start, end)
-    self.buffer.apply_tag(self.tag['font'], start, end)
-    self.last = self.tokens
-    for token in self.tokens:
-      self.buffer.apply_tag(self.tag[token.token], \
-                            token.start_iter, \
-                            token.end_iter)
-      if (token.token == 'comment'):
-        self.buffer.apply_tag(self.tag['comment2'], \
-                              token.start_iter, \
-                              token.end_iter)
-
-
-  def syntaxical_analyser(self):
-    """Find keywords"""
-    tokens = self.tokens
-    self.tokens = []
-    try:
-      while (len(tokens) > 0):
-        token = tokens.pop(0)
-        # only statements, other tokens
-        # are analysed below or already founds in 
-        # the lexical analyser
-        if (token.value in STATEMENTS):
-          token.token = 'keyword'
-          self.tokens.append(token)
-          statement = token.value
-          token = tokens.pop(0)
-          # get the list containing the
-          # keywords for this statement
-          try:
-            keywords = KEYWORDS[statement]
-          except KeyError:
-            continue
-          if (type(keywords) is dict):
-            try:
-              keywords = keywords[token.value]
-              token.token = 'keyword'
-              self.tokens.append(token)
-              token = tokens.pop(0)
-            except KeyError:
-              pass
-            self.tokens.append(token)
-          # identify each token inside the statement  
-          while (token.value != ';'):
-            # only identifiers, other tokens are
-            # analysed in the lexical analyser
-            if (token.token == 'identifier'):
-              # special constants
-              if (token.value in SPECIALS):
-                token.token = 'special'
-              # buit-in data types  
-              elif (token.value in TYPES):
-                # TODO : manage composed types names
-                token.token = 'type'
-              # names operators  
-              elif (token.value in OPERATORS2):
-                token.token = 'operator'
-              # built-in functions  
-              elif (token.value in BUILTINS):
-                next = tokens.pop(0)
-                if (next.value == '('):
-                  token.token = 'function'
-                  self.tokens.append(next)
-                else:
-                  tokens.insert(0, next)
-              # built-in function that can be used without ()
-              if (token.value in BUILTINS2):
-                token.token = 'function'
-              # everything else : keywords or indentifiers  
-              else:
-                for keyword in keywords:  
-                  if (type(keyword) is list):
-                    # TODO : write the right code here
-                    # to manage composed keywords
-                    if (token.value in keyword):
-                      token.token = 'keyword'
-                  elif (token.value == keyword):
-                    token.token = 'keyword'
-            self.tokens.append(token)
-            token = tokens.pop(0)
-        self.tokens.append(token)
-    except IndexError:
-      pass
diff --git a/pgworksheet/pgw/UI.py b/pgworksheet/pgw/UI.py
deleted file mode 100644 (file)
index 6b7b596..0000000
+++ /dev/null
@@ -1,980 +0,0 @@
-# -*- coding: latin-1; -*-
-#
-# PgWorksheet - PostgreSQL Front End
-# http://pgworksheet.projects.postgresql.org/
-#
-# Copyright Â© 2004-2008 Henri Michelon & CML http://www.e-cml.org/
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details (read LICENSE.txt).
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# $Id: UI.py,v 1.26 2008/03/12 20:26:23 hmichelon Exp $
-#
-import os
-import ConfigParser
-import pygtk
-import gtk
-
-import pgw
-import pgw.Syntax
-import pgw.Undo
-
-PGW_CONNECT     = 'pgw-connect'
-PGW_CONNECTNOW  = 'pgw-connectnow'
-PGW_DISCONNECT  = 'pwg-disconnect'
-PGW_SELECTALL   = 'pwg-selectall'
-PGW_ENCODING    = 'pwg-encoding'
-PGW_ABOUT       = 'pwg-about'
-
-
-class UI:
-  """UI Construction and management"""
-
-  def __init__(self, app, app_name, app_version, pixmap_path):
-    self.pixmap_path = pixmap_path
-    self.app_version = app_version
-    self.register_stock_items()
-    self.file_dialog_path = None # last used path
-    self.file_dialog_filename = None # last used filename
-    self.define_ui(app)
-
-    self.wndmain = gtk.Window(gtk.WINDOW_TOPLEVEL)
-    self.wndmain.set_title(_('PgWorksheet - PostgreSQL SQL Tool'))
-    self.wndmain.set_icon_from_file(os.path.join(pixmap_path,
-                                                 "pgworksheet-32.png"))
-    self.wndmain.add_accel_group(self.accelgroup)
-    self.wndmain.set_default_size(640, 480)
-    self.wndmain.connect('window-state-event', self.on_wndmain_state)
-    self.wndmain.connect('configure-event', self.on_wndmain_configure)
-    self.wndmain.connect('destroy', app.on_wndmain_destroy)
-    self.wndmain.connect('delete_event', app.on_wndmain_delete)
-
-    hbox = gtk.VBox(False)
-    hbox.pack_start(self.uimanager.get_widget('/MenuBar'), False)
-    hbox.pack_start(self.uimanager.get_widget('/ToolBar'), False)
-    hbox.pack_start(self.vmain, True, True)
-    hbox.pack_start(self.statusbar, False, False)
-    self.wndmain.add(hbox)
-    
-    self.load_user_parameters()
-    self.wndmain.show_all()
-    
-
-  def load_user_parameters(self):
-    cp = ConfigParser.ConfigParser()
-    try:
-      cp.readfp(open(pgw.get_config_path(), 'r'))
-      maximized = 0
-      try:
-        maximized = int(cp.get("window", "maximized"))
-      except:
-        pass
-      if (maximized):
-        self.wndmain.maximize()
-      else:
-        width, height = self.wndmain.get_size()
-      try:
-        width = int(cp.get("window", "width"))
-      except:
-        pass
-      try:
-        height = int(cp.get("window", "height"))
-      except:
-        pass
-      self.wndmain.resize(width, height)
-      x, y = self.wndmain.get_position()
-      try:
-        x = int(cp.get("window", "x"))
-      except:
-        pass
-      try:
-        y = int(cp.get("window", "y"))
-      except:
-        pass
-      self.wndmain.move(x, y)
-      try:
-        self.vmain.set_position(int(cp.get("window", "divider")))
-      except:
-        pass
-    except IOError:
-      pass
-    return cp
-
-
-  def message_dialog(self, msg, type, buttons = gtk.BUTTONS_OK):
-    dialog = gtk.MessageDialog(self.wndmain,
-               gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
-               type, buttons, msg)
-    result = dialog.run()
-    dialog.destroy()
-    return result
-    
-
-  def message_box(self, msg):
-    self.message_dialog(msg, gtk.MESSAGE_INFO)
-    
-    
-  def error_box(self, msg):
-    self.message_dialog(msg, gtk.MESSAGE_ERROR)
-
-
-  def yesno_box(self, msg):
-    return self.message_dialog(msg, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO)
-
-
-  def file_dialog(self, msg, 
-                  action = gtk.FILE_CHOOSER_ACTION_OPEN,
-                  button = gtk.STOCK_OPEN):
-    fb = gtk.FileChooserDialog(msg, self.wndmain,
-                               action,
-                               (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
-                                button, gtk.RESPONSE_OK))
-    if (self.file_dialog_path is not None):
-      fb.set_current_folder_uri(self.file_dialog_path)
-    if (self.file_dialog_filename is not None):
-      fb.set_filename(self.file_dialog_filename)
-    fb.show_all()
-    result = fb.run()
-    if (result == gtk.RESPONSE_OK):
-      filename = fb.get_filename()
-    else:
-      filename = None
-    self.file_dialog_path = fb.get_current_folder_uri()
-    self.file_dialog_filename = fb.get_filename()
-    fb.destroy()
-    return filename
-
-
-  def register_stock_items(self):
-    gtk.stock_add([
-        (PGW_CONNECT, _('_Connect Server...'), gtk.gdk.CONTROL_MASK, 
-         gtk.gdk.keyval_from_name('N'), None),
-        (PGW_DISCONNECT, _('_Disconnect'), 0, -1, None),
-        (PGW_SELECTALL, _('Select _All'), gtk.gdk.CONTROL_MASK, 
-          gtk.gdk.keyval_from_name('A'), None),
-        (PGW_ENCODING, _('Character _Encoding'), 0, -1, None),
-        (PGW_ABOUT, _('_About...'), 0, -1, None),
-        (PGW_CONNECTNOW, _('_Connect'), 0, -1, None),
-                   ])
-    self.factory = gtk.IconFactory()
-    self.factory.add_default()
-    self.factory.add(PGW_CONNECTNOW, gtk.IconSet(gtk.gdk.pixbuf_new_from_file(
-                    os.path.join(self.pixmap_path, "connect.png"))))
-    self.factory.add(PGW_CONNECT, gtk.IconSet(gtk.gdk.pixbuf_new_from_file(
-                    os.path.join(self.pixmap_path, "connect.png"))))
-    self.factory.add(PGW_DISCONNECT, gtk.IconSet(gtk.gdk.pixbuf_new_from_file(
-                    os.path.join(self.pixmap_path, "disconnect.png"))))
-    self.factory.add(PGW_ABOUT, gtk.IconSet(gtk.gdk.pixbuf_new_from_file(
-                    os.path.join(self.pixmap_path, "about.png"))))
-
-
-  def define_ui(self, app):    
-    self.ui = '''<ui>
-      <menubar name="MenuBar">
-        <menu action="File">
-          <menuitem action="Connect"/>
-          <menuitem action="Disconnect"/>
-          <separator/>
-          <menuitem action="Open SQL"/>
-          <menuitem action="Save SQL"/>
-          <menuitem action="Save Results"/>
-          <menuitem action="Save All Results"/>
-          <separator/>
-          <menuitem action="Quit"/>
-        </menu>
-        <menu action="Edit">
-          <menuitem action="Undo"/>
-          <menuitem action="Redo"/>
-          <separator/>
-          <menuitem action="Cut"/>
-          <menuitem action="Copy"/>
-          <menuitem action="Paste"/>
-          <separator/>
-          <menuitem action="Select All"/>
-        </menu>
-        <menu action="Tools">
-          <menuitem action="Run SQL"/>
-        </menu>
-        <menu action="History">
-          <menuitem action="Prev Statement"/>
-          <menuitem action="Next Statement"/>
-        </menu>
-        <menu action="Help">
-          <menuitem action="About"/>
-        </menu>
-      </menubar>
-      <toolbar name="ToolBar">
-        <toolitem action="Connect"/>
-        <toolitem action="Run SQL"/>
-        <toolitem action="Prev Statement"/>
-        <toolitem action="Next Statement"/>
-        <separator/>
-        <toolitem action="Open SQL"/>
-        <toolitem action="Save SQL"/>
-        <separator/>
-        <toolitem action="Cut"/>
-        <toolitem action="Copy"/>
-        <toolitem action="Paste"/>
-      </toolbar>
-      <accelerator action="Run SQL 2"/>
-      <accelerator action="Run SQL 3"/>
-    </ui>'''
-
-    self.undo = pgw.Undo.Undo()
-    self.uimanager = gtk.UIManager()
-    self.accelgroup = self.uimanager.get_accel_group()
-    self.actiongroup = gtk.ActionGroup('UIManagerMenuBar')
-    self.actiongroup.add_actions([
-        ('File', None, _('_File')),
-          ('Connect', PGW_CONNECT, None, None,
-            _('Connect to a database'), app.on_menu_connect),
-          ('Disconnect', PGW_DISCONNECT, None, '',
-            _('Disconnect from the database'), app.on_menu_disconnect),
-          ('Open SQL', gtk.STOCK_OPEN, _('_Open SQL queries...'), None,
-            _('Load SQL queries from a file'), app.on_menu_opensql),
-          ('Save SQL', gtk.STOCK_SAVE, _('_Save SQL queries...'), None,
-            _('Save SQL queries to a file'), app.on_menu_savesql),
-          ('Save Results', gtk.STOCK_SAVE, _('Save _Results...'), '<control>R',
-            _('Save the results to a file'), app.on_menu_saveresults),
-          ('Save All Results', gtk.STOCK_SAVE, _('Save _All Results...'),
-            '<control><shift>R',
-            _('Save all the results to a file'), app.on_menu_saveallresults),
-          ('Quit', gtk.STOCK_QUIT, None, None,
-            _('Quit the Program'), app.on_wndmain_destroy),
-        ('Edit', None, _('_Edit')),
-          ('Undo', gtk.STOCK_UNDO, None, '<control>Z',
-            _('Undo the last action'), lambda w: self.undo.undo()),
-          ('Redo', gtk.STOCK_REDO, None, '<shift><control>Z',
-            _('Redo the last action'), lambda w: self.undo.redo()),
-          ('Cut', gtk.STOCK_CUT, None, None,
-            _('Cut selection to the clipboard'), app.on_menu_cut),
-          ('Copy', gtk.STOCK_COPY, None, None,
-            _('Copy selection to the clipboard'), app.on_menu_copy),
-          ('Paste', gtk.STOCK_PASTE, None, None,
-            _('Paste the content of the clipboard'), app.on_menu_paste),
-          ('Select All', PGW_SELECTALL, None, None,
-            _('Select all the text'), app.on_menu_selectall),
-        ('View', None, _('_View')),
-          ('Encoding', PGW_ENCODING, None, None, _('Select the character \
-              encoding for display'), app.on_menu_selectall),
-        ('Tools', None, _('_Tools')),
-          ('Run SQL', gtk.STOCK_EXECUTE, None, "<control>Return",
-            _('Execute the content of the SQL buffer'), app.on_menu_runsql),
-        ('History', None, _('_History')),
-        ('Prev Statement', gtk.STOCK_GO_BACK, _('_Previous statements'),
-            "<control>Page_Down",
-            _('Go backward in the executed statements history'), 
-            app.on_menu_prevsql),
-          ('Next Statement', gtk.STOCK_GO_FORWARD, _('_Next statements'),
-            "<control>Page_Up",
-            _('Go forward in the executed statements history'), 
-            app.on_menu_nextsql),
-        ('Help', None, _('_Help')),
-          ('About', PGW_ABOUT, None, '',
-            _('More information about this application'), app.on_menu_about),
-        ('Run SQL 2', gtk.STOCK_EXECUTE, None, "F9", None, app.on_menu_runsql),
-        ('Run SQL 3', gtk.STOCK_EXECUTE, None, "F5", None, app.on_menu_runsql),
-                                 ])
-    self.uimanager.insert_action_group(self.actiongroup, 0)
-    self.uimanager.add_ui_from_string(self.ui)
-    self.uimanager.get_widget('/MenuBar/Help').\
-      set_right_justified(True)
-    self.enable_disconnect(False)
-    self.enable_runsql(False)
-    self.enable_prevsql(False)
-    self.enable_nextsql(False)
-    self.enable_saveresult(False)
-    self.create_vpaned(app)
-    self.create_statusbar()
-    self.uimanager.get_widget('/ToolBar').set_style(gtk.TOOLBAR_ICONS)
-
-
-  def create_vpaned(self, app):
-    self.vmain = gtk.VPaned()
-    self.vmain.connect("event", self.on_vpaned_accept)
-    scroll = gtk.ScrolledWindow()
-    scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-    scroll.set_property("height-request", 150)
-    scroll.set_shadow_type(gtk.SHADOW_NONE)
-    self.sqlbuffer = gtk.TextBuffer()
-    self.sqlbuffer.connect('delete-range', self.undo.text_deleted)
-    self.sqlbuffer.connect('insert-text', self.undo.text_inserted)
-    self.syntax = pgw.Syntax.Syntax(self.sqlbuffer)
-    self.buffer_handlers = []
-    self.buffer_handlers.append(self.sqlbuffer.connect('delete-range',  
-                                self.syntax.text_deleted))
-    self.buffer_handlers.append(self.sqlbuffer.connect('insert-text', 
-                                self.syntax.text_inserted))
-    self.buffer_handlers.append(self.sqlbuffer.connect('changed', 
-                                self.syntax.text_changed))
-    self.buffer_handlers.append(self.sqlbuffer.connect('changed', 
-                                app.on_text_change))
-    self.sqlview = gtk.TextView(self.sqlbuffer)
-    self.sqlview.connect('focus-in-event', app.on_sqlview_focus_in)
-    self.sqlview.connect('focus-out-event', app.on_sqlview_focus_out)
-    self.sqlview.connect('key-press-event', app.on_sqlview_keypress)
-    scroll.add(self.sqlview)
-    self.vmain.add1(scroll)
-    self.resulttab = gtk.Notebook()
-    self.resulttab.set_tab_pos(gtk.POS_BOTTOM)
-    self.resulttab.set_scrollable(True)
-    resultview = gtk.Viewport()
-    resultview.set_shadow_type(gtk.SHADOW_IN)
-    resultview.add(self.resulttab)
-    self.vmain.add2(resultview)
-
-
-  def create_statusbar(self):
-    self.statusbar = gtk.Statusbar()
-    self.statusbar.set_border_width(0)
-
-    f = self.statusbar.get_children()[0]
-    f.set_shadow_type(gtk.SHADOW_IN)
-    self.status_result = f.get_children()
-    self.status_result = self.status_result[0]
-    self.statusbar.set_child_packing(f, True, True, 0, gtk.PACK_START)
-
-    self.status_connect = gtk.Label();
-    self.status_connect.set_justify(gtk.JUSTIFY_LEFT)
-    f = gtk.Frame()
-    f.set_shadow_type(gtk.SHADOW_IN)
-    f.add(self.status_connect)
-    self.statusbar.pack_start(f, False, False)
-
-    self.status_version = gtk.Label();
-    f = gtk.Frame()
-    f.set_shadow_type(gtk.SHADOW_IN)
-    f.add(self.status_version)
-    self.statusbar.pack_start(f, False, False)
-
-    f = gtk.Label('     ')
-    self.statusbar.pack_start(f, False, False)
-
-
-  def status(self, connect, version):
-    """Update the status bar text"""
-    self.status_connect.set_markup(" " + connect + " ")
-    self.status_version.set_markup(" " + version + " ")
-
-
-  def setfocus_sqlbuffer(self):
-    self.sqlview.grab_focus()
-
-
-  def enable_disconnect(self, state = True):
-    self.uimanager.get_widget('/MenuBar/File/Disconnect').\
-      set_sensitive(state)
-
-
-  def enable_saveresult(self, state = True):
-    self.uimanager.get_widget('/MenuBar/File/Save All Results').\
-      set_sensitive(state)
-    self.uimanager.get_widget('/MenuBar/File/Save Results').\
-      set_sensitive(state)
-
-
-  def enable_runsql(self, state = True):    
-    self.uimanager.get_widget('/MenuBar/Tools/Run SQL').\
-      set_sensitive(state)
-    self.uimanager.get_widget('/ToolBar/Run SQL').\
-      set_sensitive(state)
-
-
-  def enable_cut(self, state = True):
-    self.uimanager.get_widget('/MenuBar/Edit/Cut').\
-      set_sensitive(state)
-    self.uimanager.get_widget('/ToolBar/Cut').\
-      set_sensitive(state)
-
-
-  def enable_copy(self, state = True):
-    self.uimanager.get_widget('/MenuBar/Edit/Copy').\
-      set_sensitive(state)
-    self.uimanager.get_widget('/ToolBar/Copy').\
-      set_sensitive(state)
-
-
-  def enable_selectall(self, state = True):
-    self.uimanager.get_widget('/MenuBar/Edit/Select All').\
-      set_sensitive(state)
-
-
-  def enable_paste(self, state = True):
-    self.uimanager.get_widget('/MenuBar/Edit/Paste').\
-      set_sensitive(state)
-    self.uimanager.get_widget('/ToolBar/Paste').\
-      set_sensitive(state)
-
-
-  def enable_prevsql(self, state = True):
-    self.uimanager.get_widget('/MenuBar/History/Prev Statement').\
-      set_sensitive(state)
-    self.uimanager.get_widget('/ToolBar/Prev Statement').\
-      set_sensitive(state)
-
-
-  def enable_nextsql(self, state = True):
-    self.uimanager.get_widget('/MenuBar/History/Next Statement').\
-      set_sensitive(state)
-    self.uimanager.get_widget('/ToolBar/Next Statement').\
-      set_sensitive(state)
-
-
-  def get_text(self, buffer):
-    """Return the text of a widget"""
-    c1 = buffer.get_start_iter()
-    c2 = buffer.get_end_iter()
-    return buffer.get_slice(c1, c2, True)
-
-
-  def get_sqlbuffer_text(self):
-    return self.get_text(self.sqlbuffer)
-
-
-  def set_sqlbuffer_text(self, text):
-    self.sqlbuffer.set_text(text)
-
-  
-  def on_connect_event(self, widget, event):
-    if ((not self.entry_password.is_focus()) and
-         self.viewconn.is_focus()):
-        self.entry_password.grab_focus()
-
-    
-  def connect_dialog(self, app, host, port, user, database, overwrite_entry):
-    dlg = gtk.Dialog(_('Database connection'),
-                     self.wndmain,
-                     gtk.DIALOG_MODAL or gtk.DIALOG_DESTROY_WITH_PARENT,
-                     ((gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
-                       PGW_CONNECTNOW, gtk.RESPONSE_OK)))
-    dlg.set_resizable(False)
-
-    mbox = gtk.HBox()
-    box = gtk.Frame()
-    self.storeconn = gtk.ListStore(str, str)
-    self.viewconn = gtk.TreeView(self.storeconn)
-    cell = gtk.CellRendererText()
-    column = gtk.TreeViewColumn(_('5 Previous connections'))
-    column.pack_start(cell, True)
-    column.add_attribute(cell, 'text', 0)
-    column.set_sort_column_id(0)
-    self.viewconn.append_column(column)
-    self.viewconn.connect('cursor-changed', app.on_dlgconnect_change)
-    box.add(self.viewconn)
-    mbox.pack_start(box, True, True)
-
-    hbox = gtk.HBox(False)
-    hbox.set_border_width(10)
-    hbox.set_spacing(10)
-
-    box = gtk.VBox(True)
-    box.set_spacing(10)
-    lbl = gtk.Label(_('Host'))
-    lbl.set_alignment(0, 0.1)
-    box.pack_start(lbl, True, True)
-    lbl = gtk.Label(_('Port'))
-    lbl.set_alignment(0, 0.1)
-    box.pack_start(lbl, True, True)
-    lbl = gtk.Label(_('User'))
-    lbl.set_alignment(0, 0.1)
-    box.pack_start(lbl, True, True)
-    lbl = gtk.Label(_('Password'))
-    lbl.set_alignment(0, 0.1)
-    box.pack_start(lbl, True, True)
-    lbl = gtk.Label(_('Database'))
-    lbl.set_alignment(0, 0.1)
-    box.pack_start(lbl, True, True)
-    hbox.pack_start(box, False, False)
-
-    box = gtk.VBox(False)
-    box.set_spacing(10)
-    self.entry_host = gtk.Entry()
-    self.entry_host.connect('activate', lambda w: dlg.response(gtk.RESPONSE_OK))
-    box.pack_start(self.entry_host, True, True)
-    self.entry_port = gtk.Entry()
-    self.entry_port.connect('activate', lambda w: dlg.response(gtk.RESPONSE_OK))
-    box.pack_start(self.entry_port, True, True)
-    self.entry_user = gtk.Entry()
-    self.entry_user.connect('activate', lambda w: dlg.response(gtk.RESPONSE_OK))
-    box.pack_start(self.entry_user, True, True)
-    self.entry_password = gtk.Entry()
-    self.entry_password.set_visibility(False)
-    self.entry_password.connect('activate', lambda w: dlg.response(gtk.RESPONSE_OK))
-    box.pack_start(self.entry_password, True, True)
-    self.entry_database = gtk.Entry()
-    self.entry_database.connect('activate', lambda w: dlg.response(gtk.RESPONSE_OK))
-    box.pack_start(self.entry_database, True, True)
-    hbox.pack_start(box, True, True)
-
-    mbox.pack_start(hbox, True, True)
-
-    dlg.vbox.pack_start(mbox, True, True, 0)
-    app.on_dlgconnect_map(None)
-    if (overwrite_entry or (not self.storeconn.iter_n_children(None))):
-      self.entry_host.set_text(host)
-      self.entry_port.set_text(str(port))
-      self.entry_user.set_text(user)
-      self.entry_database.set_text(database)
-    dlg.set_default_response(gtk.RESPONSE_OK)
-    dlg.connect('event-after', self.on_connect_event)
-    dlg.vbox.show_all()
-    self.entry_password.grab_focus()
-    result = None
-    if (dlg.run() == gtk.RESPONSE_OK):
-      result = (self.entry_host.get_text(), 
-                self.entry_port.get_text(),
-                self.entry_user.get_text(),
-                self.entry_password.get_text(),
-                self.entry_database.get_text())
-    dlg.destroy()
-    return result
-
-
-  def write_config(self, cp):
-    try:
-      cp.write(open(pgw.get_config_path(), 'w'))
-    except IOError:
-      pass
-
-
-  def on_vpaned_accept(self, widget, event):
-    cp = ConfigParser.ConfigParser()
-    try:    
-      cp.readfp(open(pgw.get_config_path(), 'r'))
-    except IOError:
-      pass
-    if (not cp.has_section("window")):
-      cp.add_section("window")
-    cp.set("window", "divider",  str(widget.get_position()))
-    self.write_config(cp)
-
-
-  def on_wndmain_state(self, widget, event):
-    cp = ConfigParser.ConfigParser()
-    try:    
-      cp.readfp(open(pgw.get_config_path(), 'r'))
-    except IOError:
-      pass
-    if (not cp.has_section("window")):
-      cp.add_section("window")
-    if (event.new_window_state == gtk.gdk.WINDOW_STATE_MAXIMIZED):  
-      cp.set("window", "maximized",  "1")
-    else:
-      cp.set("window", "maximized",  "0")
-    self.write_config(cp)
-
-
-  def on_wndmain_configure(self, widget, event):
-    cp = ConfigParser.ConfigParser()
-    try:    
-      cp.readfp(open(pgw.get_config_path(), 'r'))
-    except IOError:
-      pass
-    if (not cp.has_section("window")):
-      cp.add_section("window")
-    x, y = widget.get_position()
-    cp.set("window", "x",  x)
-    cp.set("window", "y",  y)
-    width, height = widget.get_size()
-    cp.set("window", "width",  width)
-    cp.set("window", "height",  height)
-    self.write_config(cp)
-
-
-  def about_dialog(self):
-    dlg = gtk.Dialog(_('About PgWorksheet'),
-                     self.wndmain,
-                     gtk.DIALOG_MODAL or gtk.DIALOG_DESTROY_WITH_PARENT,
-                     ((gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)))
-    nbk = gtk.Notebook()
-    
-    box = gtk.VBox(False)
-
-    lbl = gtk.Label()
-    lbl.set_markup('''
-<b>PgWorksheet - PostgreSQL Front End</b>
-Version ''' + self.app_version + '''
-<u>http://pgworksheet.projects.postgresql.org/</u>
-
-Copyright Â© 2004-2006, Henri Michelon and CML
-<u>http://www.e-cml.org/</u>
-    ''')
-    lbl.set_justify(gtk.JUSTIFY_CENTER)
-    lbl.set_padding(10, 10)
-    box.pack_start(lbl, True)
-    lbl = gtk.Label()
-    lbl.set_markup('''
-<b>Internationalization:</b>
-French : Henri Michelon &lt;[email protected]&gt;
-Japanese : Tadashi Jokagi &lt;[email protected]&gt;
-    ''')
-    lbl.set_padding(10, 0)
-    box.pack_start(lbl, True)
-    pix = gtk.Image()
-    pix.set_from_file(os.path.join(self.pixmap_path, "pgworksheet.png"))
-    pix.set_padding(10, 10)
-    box.pack_start(pix, False)
-    nbk.append_page(box, gtk.Label(_('About')))
-
-    txt = gtk.TextBuffer()
-    txt.set_text('''
-                   GNU GENERAL PUBLIC LICENSE
-                      Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                           Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-\f
-                   GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-\f
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-\f
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-\f
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-                           NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-                    END OF TERMS AND CONDITIONS
-\f
-           How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
-    ''')
-    scroll = gtk.ScrolledWindow()
-    scroll.add(gtk.TextView(txt))
-    nbk.append_page(scroll, gtk.Label(_('License')))
-    
-    dlg.vbox.pack_start(nbk, True, True, 0)
-    nbk.show_all()
-    dlg.run()
-    dlg.destroy()
diff --git a/pgworksheet/pgw/Undo.py b/pgworksheet/pgw/Undo.py
deleted file mode 100644 (file)
index 6f29ed9..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-# -*- coding: latin-1; -*-
-#
-# PgWorksheet - PostgreSQL Front End
-# http://pgworksheet.projects.postgresql.org/
-#
-# Copyright Â© 2004-2008 Henri Michelon & CML http://www.e-cml.org/
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details (read LICENSE.txt).
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# $Id: Undo.py,v 1.4 2008/03/12 20:26:23 hmichelon Exp $
-#
-
-# maxium size of the undo stack
-UNDO_MAX = 1000
-
-
-class UndoAction:
-  """A user action : insert or delete"""
-
-  def __init__(self, buffer, type, start, end, value):
-    self.buffer = buffer
-    self.type = type
-    self.start = start
-    self.end = end
-    self.value = value
-    
-
-class Undo:
-  """Records user actions and apply or revert them"""
-
-  def __init__(self):
-    self.undo_stack = []
-    self.redo_stack = []
-    # locking is used to avoid recording
-    # our own undo/redo actions
-    self.lock = False
-
-
-  def reset(self):
-    """empty the stacks to restart the undo action"""
-    self.undo_stack = []
-    self.redo_stack = []
-
-
-  def text_inserted(self, buffer, iter, text, length):
-    """Called by Gtk when text is inserted in a buffer"""
-    if (not self.lock):
-      if (len(self.undo_stack) >= UNDO_MAX):
-        self.undo_stack.pop(0)
-      self.undo_stack.append(UndoAction(buffer, "insert",
-                                iter.get_offset(), iter.get_offset() + length,
-                                text))
-
-
-  def text_deleted(self, buffer, start, end):
-    """Called by Gtk when text is deleted from a buffer"""
-    if (not self.lock):
-      if (len(self.undo_stack) >= UNDO_MAX):
-        self.undo_stack.pop(0)
-      self.undo_stack.append(UndoAction(buffer, "delete",
-                                start.get_offset(), end.get_offset(),
-                                buffer.get_text(start, end)))
-
-      
-  def undo(self):
-    """Revert the last action"""
-    if (len(self.undo_stack) == 0):
-      return
-    self.lock = True
-    action = self.undo_stack.pop()
-    if (action.type == "insert"):
-      action.buffer.delete(action.buffer.get_iter_at_offset(action.start),
-                           action.buffer.get_iter_at_offset(action.end))
-    elif (action.type == "delete"):
-      action.buffer.insert(action.buffer.get_iter_at_offset(action.start),
-                           action.value)
-    self.redo_stack.append(action)
-    self.lock = False
-
-
-  def redo(self):
-    """Apply the last reverted action"""
-    if (len(self.redo_stack) == 0):
-      return
-    self.lock = True
-    action = self.redo_stack.pop()
-    if (action.type == "insert"):
-      action.buffer.insert(action.buffer.get_iter_at_offset(action.start),
-                           action.value)
-    elif (action.type == "delete"):
-      action.buffer.delete(action.buffer.get_iter_at_offset(action.start),
-                           action.buffer.get_iter_at_offset(action.end))
-    self.undo_stack.append(action)
-    self.lock = False
diff --git a/pgworksheet/pgw/__init__.py b/pgworksheet/pgw/__init__.py
deleted file mode 100644 (file)
index 2d6ffa0..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-# -*- coding: latin-1; -*-
-#
-# PgWorksheet - PostgreSQL Front End
-# http://pgworksheet.projects.postgresql.org/
-#
-# Copyright Â© 2004-2008 Henri Michelon & CML http://www.e-cml.org/
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details (read LICENSE.txt).
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# $Id: __init__.py,v 1.10 2008/03/12 20:26:23 hmichelon Exp $
-#
-import sys
-import os
-import string
-
-
-def mswindows():
-    """Return TRUE is we run under Microsoft Windows"""
-    return sys.platform == "win32"
-
-
-def get_user_encoding():
-    if (mswindows()):
-      return "ISO-8859-1" #"UTF-8"
-    try:
-      enc = os.environ['MM_CHARSET']
-      return enc
-    except KeyError:
-      try:
-        enc = os.environ['LANG']
-      except KeyError:
-        try:
-          enc = os.environ['LC_LANG']
-        except KeyError:
-          try:
-            enc = os.environ['LC_ALL']
-          except KeyError:
-            return "ISO8859-1"
-    parts = string.split(enc, '.')
-    if (len(parts) > 1) :
-      return parts[1]
-    return "ISO8859-1"
-
-
-def set_proportional(buffer):
-    """Change the font of a widget to proportional"""
-    tagname = 'font-' + str(buffer)
-    try:
-      font = buffer.create_tag(tagname)
-      if (mswindows()):
-        font.set_property('font', 'Courier New 10')
-      else:
-        font.set_property('family', 'monospace')
-      buffer.apply_tag(font, buffer.get_start_iter(), buffer.get_end_iter())
-    except TypeError: # tag already exists
-      buffer.apply_tag_by_name(tagname, buffer.get_start_iter(), buffer.get_end_iter())
-
-
-def get_user_configdir():
-    """Return the directory where the configuration file is stored"""
-    if (mswindows()):
-      try:
-        return os.environ['USERPROFILE']
-      except KeyError:
-        try:
-          return os.environ['ALLUSERSPROFILE']
-        except KeyError:
-          return os.environ['SYSTEMROOT']
-    else:
-      return os.environ['HOME']
-
-
-def get_config_path():
-    return os.path.join(get_user_configdir(), '.pgworksheet')
diff --git a/pgworksheet/pgworksheet b/pgworksheet/pgworksheet
deleted file mode 100755 (executable)
index 301e4e4..0000000
+++ /dev/null
@@ -1,606 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: latin-1; -*-
-#
-# PgWorksheet - PostgreSQL Front End
-# http://pgworksheet.projects.postgresql.org/
-#
-# Copyright Â© 2004-2008 Henri Michelon & CML http://www.e-cml.org/
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details (read LICENSE.txt).
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# $Id: pgworksheet,v 1.94 2008/03/13 11:05:32 hmichelon Exp $
-#
-import os
-import sys
-# Application parameters
-app_name    = 'pgworksheet'
-app_version = '1.9'
-# Default pixmap path
-pixmap_path = '@PIXMAP_PATH@'
-# Find current pixmap path
-if (not os.access(os.path.join(pixmap_path, 'pgworksheet-32.png'), os.F_OK)):
-  pixmap_path = os.path.join(sys.prefix, 'share/pixmaps/pgworksheet')
-if (not os.access(os.path.join(pixmap_path, 'pgworksheet-32.png'), os.F_OK)):
-  pixmap_path = os.path.join(os.path.dirname(sys.argv[0]), 'pixmaps/pgworksheet')
-# Find current locale path
-locale_path = '@LOCALE_PATH@'
-if (not os.access(os.path.join(locale_path, 'fr/LC_MESSAGES/pgworksheet.mo'), os.F_OK)):
-  locale_path = os.path.join(sys.prefix, 'share/locale')
-if (not os.access(os.path.join(locale_path, 'fr/LC_MESSAGES/pgworksheet.mo'), os.F_OK)):
-  locale_path = os.path.join(os.path.dirname(sys.argv[0]), 'locale')
-
-import string
-import gettext
-import locale
-
-# Initialize I18N
-if sys.platform == 'win32':
-    try:
-      # try to get the default language
-        lang = gettext.translation(app_name, locale_path, 
-              [ locale.getdefaultlocale()[0] ])
-        lang.install()
-    except IOError:
-        # fallback to the default method
-        gettext.bindtextdomain(app_name, locale_path)
-        gettext.textdomain(app_name)
-        gettext.install(app_name, locale_path, unicode=1)
-else:
-    gettext.bindtextdomain(app_name, locale_path)
-    gettext.textdomain(app_name)
-    gettext.install(app_name, locale_path, unicode=1)
-
-
-if sys.platform == 'win32':
-  # win32 platform, add the "lib" folder to the system path
-  os.environ['PATH'] = "gtk/bin;gtk/lib;" + os.environ['PATH']
-  import pygtk
-  # search for the postgresql installation
-  import _winreg
-  reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
-  try:
-      keyname = "SOFTWARE\PostgreSQL\Installations"
-      key = _winreg.OpenKey(reg, keyname)
-      keyname = keyname + "\\" + _winreg.EnumKey(key, 0);
-      _winreg.CloseKey(key)
-      key = _winreg.OpenKey(reg, keyname)
-      val, typ = _winreg.QueryValueEx(key, "Base Directory")
-      _winreg.CloseKey(key)
-      os.environ['PATH'] = val + "\\bin;" + os.environ['PATH']
-  except WindowsError:
-       msg = _("Please install PostgreSQL.\n\nDownload it at http://www.postgresql.org/.\n\nNote : if you use PgWorksheet to connect to remote databases only, you don't need to install PostgreSQL as a service.")
-       print(msg)
-       import gtk
-       dialog = gtk.MessageDialog(None,
-                                  gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
-                                  gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, msg)
-       result = dialog.run()
-       dialog.destroy()
-       sys.exit(0)
-else:
-  import pygtk
-  # not win32, ensure version 2.0 of pygtk is imported
-  pygtk.require('2.0')
-  
-import gtk
-import ConfigParser
-
-import pgw
-import pgw.UI
-import pgw.RunSQL
-import pgw.Execute
-import pgw.DBConnection
-
-# maximum entries in the SQL queries history
-PGW_MAX_HISTORY             = 100
-# maximum entries in the connection parameters history
-PGW_MAX_CONNECTION_HISTORY  = 5
-
-
-class PgWorksheet:
-
-  def __init__(self, app_name, app_version, pixmap_path): 
-    # Build UI
-    self.ui = pgw.UI.UI(self, app_name, app_version, pixmap_path)
-    # Default connection state : not connected
-    self.db = None
-    self.disconnect()
-    # Initialize prev/next query lifos for history
-    self.prev_statements = []
-    self.next_statements = []
-    self.load_history()
-    self.prev_saved = 1 
-    # Display connection dialog on startup
-    self.on_menu_connect(None)
-    # Start application
-    gtk.main()
-
-
-  def add_prevstatement(self, sql):
-    """Add a query to the previous queries lifo"""
-    # do not add the same query two times
-    if (len(self.prev_statements) > 0):
-      prev = self.prev_statements[len(self.prev_statements)-1]
-      if (prev == sql): return
-    # add the query to the lifo
-    self.prev_statements.append(sql)
-    self.ui.enable_prevsql(len(self.prev_statements) > 0)
-
-
-  def get_history_path(self):
-    """Returns the path to the configuration file"""
-    return os.path.join(pgw.get_user_configdir(), '.pgworksheet_history');
-
-
-  def save_history(self):
-    """Save the history in a text file"""
-    try:
-      fd = open(self.get_history_path(), 'w')
-      self.add_prevstatement(self.ui.get_sqlbuffer_text())
-      for sql in self.prev_statements:
-        fd.write("\n#$#\n")
-        fd.write(string.rstrip(sql))
-      for sql in self.next_statements:
-        fd.write("\n#$#\n")
-        fd.write(string.rstrip(sql))
-      fd.write("\n#$#\n")
-      fd.close()
-    except IOError:
-      pass 
-
-
-  def load_history(self):
-   """Load the history from a text file"""
-   try:
-     fd = open(self.get_history_path(), 'r')
-     sql = ''
-     count = 0
-     for line in fd:
-       line = string.rstrip(line)
-       if (line == '') :
-         continue
-       try:
-         line = unicode(line, 'UTF-8')
-       except UnicodeDecodeError:
-         try:
-           line = unicode(line, pgw.get_user_encoding())
-         except UnicodeDecodeError:
-           pass
-       if (line == '#$#'):
-         if (len(sql) > 0):
-           self.prev_statements.append(sql)
-           count = count + 1
-           sql = ''
-         continue
-       sql += line
-       sql += '\n'
-     if (len(sql) > 0):
-       self.prev_statements.append(sql)
-     fd.close()     
-     if (count > PGW_MAX_HISTORY):
-       self.prev_statements = self.prev_statements[count - PGW_MAX_HISTORY : count]
-     self.ui.enable_prevsql(len(self.prev_statements) > 0)
-   except IOError:
-     pass
-
-
-  def is_connected(self):
-    """Return TRUE if connected to a database"""
-    if (self.db is None):
-      return None
-    else:
-      return self.db.is_connected()
-
-
-  def connect(self, host = None, port = None, db = None, 
-              user = None, password = None):
-    """Connect to a database"""
-    self.ui.wndmain.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
-    self.ui.status(_('Trying to connect as <b>%(user)s</b> to <b>%(db)s</b> on <b>%(host)s</b>') %
-        {'user':user, 'db':db, 'host':host}, _('connecting...'))
-    while (gtk.events_pending() == True):
-      gtk.main_iteration_do(False)
-    # Disconnect then re-connect
-    self.disconnect()
-    self.db = pgw.DBConnection.DBConnection(host, port, db, user, password)
-    # we are connected
-    if (self.is_connected()):
-      # update the UI to reflect the connection state
-      self.ui.enable_disconnect()
-      self.ui.enable_runsql()
-      self.ui.status(_('connected as <b>%(user)s</b> to <b>%(db)s</b> on <b>%(host)s</b>') %
-          {'user':user, 'db':db, 'host':host}, self.db.pgversion())
-      new_conn = "%s,%s,%s,%s" % (host, port, db, user)
-      # update the connection history
-      n = 0
-      for conn in self.all_connections:
-        # remove the connection from the history if it already exists
-        if (conn == new_conn):
-          self.all_connections.pop(n)
-          break
-        n = n + 1
-      # add the connection to the history, making it the first of the list
-      self.all_connections.insert(0, new_conn)
-      # save the connection history in the config file
-      cp = ConfigParser.ConfigParser()
-      try:
-        cp.readfp(open(pgw.get_config_path(), 'r'))
-      except IOError:
-        pass
-      if (not cp.has_section("connections")):
-        cp.add_section("connections")
-      n = 0
-      while ((n <= PGW_MAX_CONNECTION_HISTORY) and
-             (n < len(self.all_connections))):
-        cp.set("connections", "conn%d" % (n + 1), self.all_connections[n])
-        n = n + 1
-      try:
-        cp.write(open(pgw.get_config_path(), 'w'))
-      except IOError:
-        pass
-      # ready to type queries, give the focus to the text field
-      self.ui.setfocus_sqlbuffer()
-      # initialize the objects used to execute the queries
-      self.execute = pgw.Execute.Execute(self.db)
-      self.run = pgw.RunSQL.RunSQL(self.execute,
-                                  self.ui.sqlview,
-                                  self.ui.resulttab,
-                                  self.ui.status_result)
-    self.ui.wndmain.window.set_cursor(None)
-
-
-  def disconnect(self):
-    """Disconnect from the current database"""
-    # disconnect from the database
-    if (self.is_connected()): self.db.disconnect()
-    # destroy the objects used for this connection
-    self.db = None
-    self.execute = None
-    self.run = None
-    # update the UI to reflect the connection state
-    self.ui.status(_('not connected'), 'PgWorksheet v' + app_version)
-    self.ui.enable_disconnect(False)
-    self.ui.enable_runsql(False)
-
-
-  def on_wndmain_destroy(self, widget):
-    """Called when the application quits"""
-    self.disconnect()
-    self.save_history()
-    gtk.main_quit()
-    sys.exit(0)
-
-
-  def on_wndmain_delete(self, widget, event):
-    """Called when the user wants to close the main window"""
-    return False
-
-
-  def on_menu_connect(self, widget):
-    """Called when the user want the connection dialog box"""
-    # fill the connection dialog box with default parameters
-    try:
-      self.username = os.environ['USERNAME']
-    except KeyError:
-      try:
-        self.username = os.environ['USER']
-      except KeyError:
-        pass
-    host = 'localhost'
-    port = '5432'
-    database = 'template1'
-    username = 'postgres'
-    self.display_connect_dialog(host, port, username, database, 0)
-
-
-  def display_connect_dialog(self, host, port, username, database, overwrite_entry):
-    # display and execute the connection dialog box
-    params = self.ui.connect_dialog(self, host, port, username, database, overwrite_entry)
-    # check if the user have clicked "Cancel"
-    if (params is not None):
-      # connect to the database
-      host, port, username, passwd, database = params;
-      self.connect(host, port, database, username, passwd)
-      # error connecting to the database, retry
-      if (not self.is_connected()):
-        self.ui.error_box(_('Error connecting to %s:%s@%s:%s') % 
-                           (username, database, host, port))
-        self.display_connect_dialog(host, port, username, database, 1)
-
-
-  def on_dlgconnect_map(self, widget):      
-    """Called when the connection dialog box is displayed"""
-    # clear the connections history
-    self.all_connections = []
-    # load the connections history from the config file
-    cp = ConfigParser.ConfigParser()
-    try :
-      cp.readfp(open(pgw.get_config_path(), 'r'))
-      n = 1
-      while n <= PGW_MAX_CONNECTION_HISTORY:
-        try:
-          line = cp.get("connections", "conn%d" % n)
-          # add the connection to the connections history
-          self.all_connections.append(line)
-          host, port, db, user = string.split(line, ',')
-          # add the connections to the connections history list of the dialog box
-          self.ui.storeconn.append(["%s:%s@%s" % (user, db, host), line])
-          n = n + 1
-        except:
-          break
-      # if we have at least one connection in the history, made it the default
-      if (n > 1) :
-        # select the last used connection
-        self.ui.viewconn.set_cursor(self.ui.storeconn.get_path(
-            self.ui.storeconn.get_iter_first()))
-    except IOError:
-      pass
-
-
-  def on_dlgconnect_change(self, treeview):
-    """Called when the user choose a connection in the connection history list"""
-    # fill the connection dialog with the selected connection parameters
-    model, iter = treeview.get_selection().get_selected()
-    host, port, db, user = string.split(model.get(iter, 1)[0], ',')
-    self.ui.entry_host.set_text(host)
-    self.ui.entry_port.set_text(port)
-    self.ui.entry_database.set_text(db)
-    self.ui.entry_user.set_text(user)
-    self.ui.entry_password.set_text('')
-
-
-  def on_menu_disconnect(self, widget):
-    """Called when the user wants to disconnect from the database"""
-    self.disconnect()
-
-
-  def on_menu_opensql(self, widget):
-    """The user wants to open a file with some queries"""
-    filename = self.ui.file_dialog(_('Select a SQL text file'));
-    if (filename is not None):
-      self.ui.undo.lock = True
-      for handler in self.ui.buffer_handlers:
-        self.ui.sqlbuffer.handler_block(handler)
-      self.ui.set_sqlbuffer_text('')
-      try:
-        input = open(filename, 'r')
-        for line in input:
-          try:
-            self.ui.sqlbuffer.insert_at_cursor(unicode(line, 'UTF-8'))
-          except UnicodeDecodeError:
-            try:
-              self.ui.sqlbuffer.insert_at_cursor(unicode(line, pgw.get_user_encoding()))
-            except UnicodeDecodeError:  
-              self.ui.sqlbuffer.insert_at_cursor(line)
-      except IOError:
-        self.ui.error_box(_('Error while opening or reading from %s') %filename)
-      for handler in self.ui.buffer_handlers:
-        self.ui.sqlbuffer.handler_unblock(handler)
-      self.ui.undo.reset()
-      self.ui.undo.lock = False
-      self.ui.syntax.refresh()
-      pgw.set_proportional(self.ui.sqlbuffer)
-
-
-  def file_overwrite(self, title):
-    """Display a "Save As" dialopg box and prompt a confirmation if the selected file exists"""
-    filename = self.ui.file_dialog(title, gtk.FILE_CHOOSER_ACTION_SAVE,
-                                   gtk.STOCK_SAVE_AS);
-    if (filename is not None):
-      try:
-        os.stat(filename)
-        if (self.ui.yesno_box(_('%s already exists, overwrite ?') % filename) ==
-            gtk.RESPONSE_YES):
-          return filename
-        return self.file_overwrite(title)
-      except OSError: # file does not exists
-        return filename
-    return None  
-
-
-  def on_menu_savesql(self, widget):
-    """The user wants to save his queries"""
-    filename = self.file_overwrite(_('Save SQL queries'))
-    if (filename is not None):
-      try:
-       output = open(filename, 'w')
-       output.write(self.ui.get_sqlbuffer_text())
-      except IOError:
-        self.ui.error_box(_('Error while creating or writing %s') % filename)
-
-
-  def save_list_row(self, model, path, iter, output):
-    """Save a row of a TreeView in a tabular form"""
-    col = 0
-    while (col < model.get_n_columns()):
-      val = string.replace(model.get_value(iter, col), '"', '\"')
-      output.write('"' + val + '"')
-      col = col + 1
-      if (col < model.get_n_columns()):
-        output.write('\t')
-    output.write('\n')  
-
-  
-  def saveresults(self, widget, output):
-    """Save the content of a TreeView to a tab separated file"""
-    widget = widget.get_child()
-    if (isinstance(widget, gtk.TextView)):
-      buffer = widget.get_buffer()
-      output.write(buffer.get_text(buffer.get_start_iter(),
-                                   buffer.get_end_iter()))
-    elif (isinstance(widget, gtk.TreeView)):
-      widget.get_model().foreach(self.save_list_row, output)
-    
-
-  def on_menu_saveallresults(self, widget):
-    """The user wants to save ALL the results"""
-    if (self.ui.resulttab.get_n_pages() > 0):
-      filename = self.file_overwrite(_('Save all the results'))
-      if (filename is not None):
-        try:
-          output = open(filename, 'w')
-          page = 0
-          while page < self.ui.resulttab.get_n_pages() :
-            self.saveresults(self.ui.resulttab.get_nth_page(page), output)
-            page = page + 1
-        except IOError:
-          self.ui.error_box(_('Error while creating or writing %s') % filename)
-
-
-  def on_menu_saveresults(self, widget):
-    """The user wants to save the current result"""
-    if (self.ui.resulttab.get_n_pages() > 0):
-      filename = self.file_overwrite(_('Save the results'))
-      if (filename is not None):
-        try:
-          output = open(filename, 'w')
-          self.saveresults(self.ui.resulttab.get_nth_page(
-                          self.ui.resulttab.get_current_page()), output)
-        except IOError:
-          self.ui.error_box(_('Error while creating or writing %s') % filename)
-
-
-  def on_menu_cut(self, widget):
-    """Cut text to the clipboard"""
-    w = self.ui.wndmain.get_focus()
-    if (isinstance(w, gtk.TextView)):
-      w.emit('cut-clipboard')
-
-
-  def on_menu_copy(self, widget):
-    """Copy text to the clipboard"""
-    w = self.ui.wndmain.get_focus()
-    if (isinstance(w, gtk.TextView)):
-      w.emit('copy-clipboard')
-    elif (isinstance(w, gtk.TreeView)):
-      model, iter = w.get_selection().get_selected()
-      if (iter is not None):
-        col = 0
-        result = ''
-        while (col < model.get_n_columns()):
-          val = string.replace(model.get_value(iter, col), '"', '\"')
-          result = result + val
-          col = col + 1
-          if (col < model.get_n_columns()):
-            result = result + '\t'
-        clip = gtk.Clipboard()
-        clip.set_text(result)
-
-        
-  def on_menu_paste(self, widget):
-    """Paste from the clipboard"""
-    w = self.ui.wndmain.get_focus()
-    if (isinstance(w, gtk.TextView)):
-      w.emit('paste-clipboard')
-
-
-  def on_menu_selectall(self, widget):
-    """Select the entire text"""
-    w = self.ui.wndmain.get_focus()
-    if (isinstance(w, gtk.TextView)):
-      buffer = w.get_buffer()
-      buffer.move_mark_by_name('selection_bound', buffer.get_start_iter())
-      buffer.move_mark_by_name('insert', buffer.get_end_iter())
-
-
-  def on_sqlview_focus_in(self, widget, event):
-    self.ui.enable_cut()
-    self.ui.enable_paste()
-
-
-  def on_sqlview_focus_out(self, widget, event):
-    self.ui.enable_cut(False)
-    self.ui.enable_paste(False)
-
-
-  def on_sqlview_keypress(self, widget, event):
-    """Save the last statement in the history
-    if needed (after an execution"""
-    if (event is None) : return
-    if (event.keyval != 65507):
-      if (self.prev_saved == 0):
-        self.add_prevstatement(self.ui.get_sqlbuffer_text())
-        self.prev_saved = 1
-
-
-  def on_menu_about(self, widget):
-    self.ui.about_dialog()
-
-
-  def on_menu_runsql(self, widget):
-    """Execute the SQL queries"""
-    if (not self.is_connected()):
-      if (self.ui.yesno_box(_('Not connected to a database.\nDo you want to connect now ?')) ==
-                              gtk.RESPONSE_NO):
-        return
-      self.on_menu_connect(widget)
-      if (not self.is_connected()): 
-        return
-    self.on_text_change(widget)
-    self.prev_saved = 0
-    self.ui.wndmain.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
-    self.run.run()
-    self.ui.enable_saveresult(self.ui.resulttab.get_n_pages() > 0)
-    self.ui.wndmain.window.set_cursor(None)
-    
-
-  def on_menu_prevsql(self, widget):
-    """Display the previous statement from the history"""
-    self.ui.undo.lock = True
-    if (len(self.prev_statements) > 0):
-      s = self.prev_statements.pop()
-      self.next_statements.append(self.ui.get_sqlbuffer_text())
-      self.ui.set_sqlbuffer_text(s)
-      self.prev = s
-    self.ui.enable_prevsql(len(self.prev_statements) > 0)
-    self.ui.enable_nextsql(len(self.next_statements) > 0)
-    self.ui.undo.lock = False
-
-
-  def on_menu_nextsql(self, widget):
-    """Display the next statement from the history"""
-    self.ui.undo.lock = True
-    if (len(self.next_statements) > 0):
-      s = self.next_statements.pop()
-      self.prev_statements.append(self.ui.get_sqlbuffer_text())
-      self.ui.set_sqlbuffer_text(s)
-      self.prev = s
-    self.ui.enable_prevsql(len(self.prev_statements) > 0)
-    self.ui.enable_nextsql(len(self.next_statements) > 0)
-    self.ui.undo.lock = False
-
-  
-  def on_text_change(self, widget):
-    """The text have been changed after navigation the history"""
-    if (self.ui.undo.lock):
-      return
-    if (len(self.next_statements) > 0):
-      if (self.next_statements[0] == ''):
-        self.next_statements.pop(0)
-      self.prev_statements.append(self.prev)
-      for i in reversed(self.next_statements):
-        self.prev_statements.append(i)
-      self.next_statements = []
-    self.ui.enable_prevsql(len(self.prev_statements) > 0)
-    self.ui.enable_nextsql(len(self.next_statements) > 0)
-
-
-# Start program
-p = None
-try:
-  p = PgWorksheet(app_name, app_version, pixmap_path)
-except KeyboardInterrupt:
-  if (p is not None):
-    p.on_wndmain_destroy(None)
diff --git a/pgworksheet/pixmaps/pgworksheet.png b/pgworksheet/pixmaps/pgworksheet.png
deleted file mode 100644 (file)
index 24e6d33..0000000
Binary files a/pgworksheet/pixmaps/pgworksheet.png and /dev/null differ
diff --git a/pgworksheet/pixmaps/pgworksheet/about.png b/pgworksheet/pixmaps/pgworksheet/about.png
deleted file mode 100644 (file)
index d66bfd7..0000000
Binary files a/pgworksheet/pixmaps/pgworksheet/about.png and /dev/null differ
diff --git a/pgworksheet/pixmaps/pgworksheet/connect.png b/pgworksheet/pixmaps/pgworksheet/connect.png
deleted file mode 100644 (file)
index 6a40c1b..0000000
Binary files a/pgworksheet/pixmaps/pgworksheet/connect.png and /dev/null differ
diff --git a/pgworksheet/pixmaps/pgworksheet/disconnect.png b/pgworksheet/pixmaps/pgworksheet/disconnect.png
deleted file mode 100644 (file)
index 0769aad..0000000
Binary files a/pgworksheet/pixmaps/pgworksheet/disconnect.png and /dev/null differ
diff --git a/pgworksheet/pixmaps/pgworksheet/pgworksheet-32.png b/pgworksheet/pixmaps/pgworksheet/pgworksheet-32.png
deleted file mode 100644 (file)
index 24e6d33..0000000
Binary files a/pgworksheet/pixmaps/pgworksheet/pgworksheet-32.png and /dev/null differ
diff --git a/pgworksheet/pixmaps/pgworksheet/pgworksheet.ico b/pgworksheet/pixmaps/pgworksheet/pgworksheet.ico
deleted file mode 100644 (file)
index bda11bd..0000000
Binary files a/pgworksheet/pixmaps/pgworksheet/pgworksheet.ico and /dev/null differ
diff --git a/pgworksheet/pixmaps/pgworksheet/pgworksheet.png b/pgworksheet/pixmaps/pgworksheet/pgworksheet.png
deleted file mode 100644 (file)
index 8672762..0000000
Binary files a/pgworksheet/pixmaps/pgworksheet/pgworksheet.png and /dev/null differ
diff --git a/pgworksheet/pixmaps/pgworksheet/pgworksheet.xcf b/pgworksheet/pixmaps/pgworksheet/pgworksheet.xcf
deleted file mode 100644 (file)
index a294a55..0000000
Binary files a/pgworksheet/pixmaps/pgworksheet/pgworksheet.xcf and /dev/null differ
diff --git a/pgworksheet/setup.py b/pgworksheet/setup.py
deleted file mode 100644 (file)
index feb6b1b..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: latin-1; -*-
-#
-# Copyright (c) 2004-2008
-#      Henri Michelon
-# 
-# $Id: setup.py,v 1.14 2008/03/12 20:26:23 hmichelon Exp $
-#
-from distutils.core import setup, Extension
-
-__version__ = "1.9"
-
-setup (name = 'pgworksheet',
-       version = __version__,
-       description = 'PgWorksheet - SQL Tool for PostgreSQL',
-       url = 'http://pgworksheet.projects.postgresql.org/',
-       license = 'GPL',
-       author = 'E-CML http://www.e-cml.org/',
-       scripts = [ 'pgworksheet' ],
-       packages = [ 'pgw' ],
-       data_files = [ 
-       ('share/pixmaps',
-           [ 'pixmaps/pgworksheet.png' ]),
-               ('share/pixmaps/pgworksheet', 
-            [ 'pixmaps/pgworksheet/connect.png',
-             'pixmaps/pgworksheet/disconnect.png',
-             'pixmaps/pgworksheet/about.png',
-             'pixmaps/pgworksheet/pgworksheet-32.png',
-             'pixmaps/pgworksheet/pgworksheet.png' ]),
-        ('share/locale/fr/LC_MESSAGES',
-            [ 'locale/fr/LC_MESSAGES/pgworksheet.mo' ]),
-        ('share/locale/ja/LC_MESSAGES',
-            [ 'locale/ja/LC_MESSAGES/pgworksheet.mo' ]),
-        ('share/applications',
-            [ 'applications/pgworksheet.desktop' ]),
-        ]
-       )
index e1a90ff..4eaa9f3 100644 (file)
@@ -5,7 +5,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2007-09-08 16:50+CEST\n"
+"POT-Creation-Date: 2008-10-26 17:34+CET\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <[email protected]>\n"
@@ -15,51 +15,55 @@ msgstr ""
 "Generated-By: pygettext.py 1.5\n"
 
 
-#: ./pgw/ConnectDialog.py:98
+#: ./pgw/ConnectDialog.py:66
 msgid "Open ConnectionParameter"
 msgstr ""
 
-#: ./pgw/ConnectDialog.py:117
+#: ./pgw/ConnectDialog.py:87
+msgid "Enter Connection details:"
+msgstr ""
+
+#: ./pgw/ConnectDialog.py:90
+msgid "Local Connection"
+msgstr ""
+
+#: ./pgw/ConnectDialog.py:91
+msgid "Network Connection"
+msgstr ""
+
+#: ./pgw/ConnectDialog.py:99
 msgid "Session Name"
 msgstr ""
 
-#: ./pgw/ConnectDialog.py:118
+#: ./pgw/ConnectDialog.py:101
 msgid "Username"
 msgstr ""
 
-#: ./pgw/ConnectDialog.py:119 ./pgw/UI.py:454
+#: ./pgw/ConnectDialog.py:103 ./pgw/UI.py:471
 msgid "Password"
 msgstr ""
 
-#: ./pgw/ConnectDialog.py:120 ./pgw/UI.py:457
+#: ./pgw/ConnectDialog.py:105 ./pgw/UI.py:474
 msgid "Database"
 msgstr ""
 
-#: ./pgw/ConnectDialog.py:121 ./pgw/UI.py:445
+#: ./pgw/ConnectDialog.py:107 ./pgw/UI.py:462
 msgid "Host"
 msgstr ""
 
-#: ./pgw/ConnectDialog.py:122 ./pgw/UI.py:448
+#: ./pgw/ConnectDialog.py:109 ./pgw/UI.py:465
 msgid "Port"
 msgstr ""
 
 #: ./pgw/ConnectDialog.py:131
-msgid "Local Connection"
-msgstr ""
-
-#: ./pgw/ConnectDialog.py:132
-msgid "Network Connection"
-msgstr ""
-
-#: ./pgw/ConnectDialog.py:143
 msgid "Last Connections"
 msgstr ""
 
-#: ./pgw/ConnectDialog.py:149
+#: ./pgw/ConnectDialog.py:137
 msgid "Connect"
 msgstr ""
 
-#: ./pgw/ConnectDialog.py:154
+#: ./pgw/ConnectDialog.py:142
 msgid "Cancel"
 msgstr ""
 
@@ -67,27 +71,27 @@ msgstr ""
 msgid "Snippets"
 msgstr ""
 
-#: ./pgw/QueryView.py:31
+#: ./pgw/QueryView.py:33
 msgid "Autocompletion"
 msgstr ""
 
-#: ./pgw/QueryView.py:95 ./pgw/RunSQL.py:122
+#: ./pgw/QueryView.py:97 ./pgw/RunSQL.py:122
 msgid "Errors :"
 msgstr ""
 
-#: ./pgw/QueryView.py:104 ./pgw/RunSQL.py:131
+#: ./pgw/QueryView.py:106 ./pgw/RunSQL.py:131
 msgid "No result"
 msgstr ""
 
-#: ./pgw/QueryView.py:129 ./pgw/RunSQL.py:154
+#: ./pgw/QueryView.py:131 ./pgw/RunSQL.py:154
 msgid "query failed"
 msgstr ""
 
-#: ./pgw/QueryView.py:137 ./pgw/RunSQL.py:162
+#: ./pgw/QueryView.py:139 ./pgw/RunSQL.py:162
 msgid "log"
 msgstr ""
 
-#: ./pgw/QueryView.py:190
+#: ./pgw/QueryView.py:197
 msgid "Add"
 msgstr ""
 
@@ -99,19 +103,19 @@ msgstr ""
 msgid "Tabellenansicht"
 msgstr ""
 
-#: ./pgw/ResultView.py:120
+#: ./pgw/ResultView.py:155
 msgid "Persistent"
 msgstr ""
 
-#: ./pgw/ResultView.py:124
+#: ./pgw/ResultView.py:159
 msgid "Close"
 msgstr ""
 
-#: ./pgw/ResultView.py:172 ./pgw/ResultView.py:214
+#: ./pgw/ResultView.py:207 ./pgw/ResultView.py:253
 msgid "No Title"
 msgstr ""
 
-#: ./pgw/ResultView.py:230
+#: ./pgw/ResultView.py:269
 msgid "Error"
 msgstr ""
 
@@ -119,71 +123,83 @@ msgstr ""
 msgid "Please wait, executing the query and fetching the results..."
 msgstr ""
 
-#: ./pgw/UI.py:213
+#: ./pgw/UI.py:120
+msgid "Doing disconnect..."
+msgstr ""
+
+#: ./pgw/UI.py:127
+msgid "Connection Failed:"
+msgstr ""
+
+#: ./pgw/UI.py:134
+msgid "Connection Failed"
+msgstr ""
+
+#: ./pgw/UI.py:225
 msgid "_Connect Server..."
 msgstr ""
 
-#: ./pgw/UI.py:215
+#: ./pgw/UI.py:227
 msgid "_Disconnect"
 msgstr ""
 
-#: ./pgw/UI.py:216
+#: ./pgw/UI.py:228
 msgid "Select _All"
 msgstr ""
 
-#: ./pgw/UI.py:218
+#: ./pgw/UI.py:230
 msgid "Character _Encoding"
 msgstr ""
 
-#: ./pgw/UI.py:219
+#: ./pgw/UI.py:231
 msgid "_About..."
 msgstr ""
 
-#: ./pgw/UI.py:220
+#: ./pgw/UI.py:232
 msgid "_Connect"
 msgstr ""
 
-#: ./pgw/UI.py:261
+#: ./pgw/UI.py:273
 msgid "_File"
 msgstr ""
 
-#: ./pgw/UI.py:263
+#: ./pgw/UI.py:275
 msgid "Connect to a database"
 msgstr ""
 
-#: ./pgw/UI.py:265
+#: ./pgw/UI.py:277
 msgid "Disconnect from the database"
 msgstr ""
 
-#: ./pgw/UI.py:267
+#: ./pgw/UI.py:279
 msgid "Quit the Program"
 msgstr ""
 
-#: ./pgw/UI.py:277
+#: ./pgw/UI.py:289
 msgid "PgWorksheet - PostgreSQL SQL Tool"
 msgstr ""
 
-#: ./pgw/UI.py:418
+#: ./pgw/UI.py:435
 msgid "Database connection"
 msgstr ""
 
-#: ./pgw/UI.py:430
+#: ./pgw/UI.py:447
 msgid "5 Previous connections"
 msgstr ""
 
-#: ./pgw/UI.py:451
+#: ./pgw/UI.py:468
 msgid "User"
 msgstr ""
 
-#: ./pgw/UI.py:526
+#: ./pgw/UI.py:543
 msgid "About PgWorksheet"
 msgstr ""
 
-#: ./pgw/UI.py:558
+#: ./pgw/UI.py:575
 msgid "About"
 msgstr ""
 
-#: ./pgw/UI.py:905
+#: ./pgw/UI.py:922
 msgid "License"
 msgstr ""
 
old mode 100644 (file)
new mode 100755 (executable)
index 9ff80e9..7a8e16b 100644 (file)
@@ -33,6 +33,7 @@ class ListBox(gtk.ScrolledWindow):
         if tuple == None:
             return None
         return self.store[tuple[0]]
+
 class TextWidget(gtk.ScrolledWindow):
     def __init__(self):
         gtk.ScrolledWindow.__init__(self)