root / pykota / trunk / initscripts / upgrade-from-before-1.03.py @ 942

Revision 942, 6.6 kB (checked in by jalet, 21 years ago)

Version 1.03 is out.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1#! /usr/bin/env python
2
3# PyKota Print Quota Warning sender
4#
5# PyKota - Print Quotas for CUPS
6#
7# (c) 2003 Jerome Alet <alet@librelogiciel.com>
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
21#
22# $Id$
23#
24# THIS IS AN UPGRADE SCRIPT FOR OLD PYKOTA DATABASES TO THE 1.03 VERSION
25#
26
27import sys
28import os
29try :
30    import pg
31except ImportError :   
32    sys.stderr.write("The PyGreSQL Python module doesn't seem to be available. ABORTED.\n")
33    sys.exit(-1)
34
35def dump_old_database() :
36    """Dumps the existing PyKota database to a file, to avoir loosing data.
37   
38       Returns 1 if dump is successfull, 0 if it isn't.
39    """   
40    pipeinput = os.popen("pg_dump -C -D -N -U postgres -f pykota-dump.sql pykota")
41    dummy = pipeinput.read()
42    return (pipeinput.close() is None) or 0
43
44def create_new_database() :
45    """Creates the empty database."""
46    pipeinput = os.popen("psql -U postgres template1 <pykota-postgresql.sql")
47    dummy = pipeinput.read()
48    return (pipeinput.close() is None) or 0
49   
50def restore_original_database() :
51    """Creates the empty database."""
52    pipeinput = os.popen("psql -U postgres template1 <pykota-dump.sql")
53    dummy = pipeinput.read()
54    return (pipeinput.close() is None) or 0
55   
56def open_database(dbname="pykota") :
57    """Returns the database object or None if we can't connect to it."""
58    try :
59        pykotadb = pg.connect(dbname, user="postgres")
60    except pg.error, msg :     
61        sys.stderr.write("%s\n" % msg)
62        return 
63    else :   
64        return pykotadb
65       
66       
67def doQuote(field) :
68    """Quotes a field for use as a string in SQL queries."""
69    if type(field) == type(0) : # TODO : do something safer
70        typ = "decimal"
71    else :   
72        typ = "text"
73    return pg._quote(field, typ)
74       
75def main() :
76    """Does the work."""
77   
78    # First we make a dump of the old database
79    print "Dumping old database for safety...",
80    if not dump_old_database() :
81        sys.stderr.write("Error while dumping old database. ABORTED.\n")
82        return -1
83    print "Done."
84       
85    # Second we try to connect to it   
86    print "Extracting datas from old database...", 
87    db = open_database()
88    if db is None :
89        sys.stderr.write("Impossible to connect to old PyKota database. ABORTED.\nAre you sure you are upgrading an existing installation ?\n")
90        return -1
91   
92    # Third we extract datas
93    oldprinters = db.query("SELECT * FROM printers ORDER BY id;")
94    oldusers = db.query("SELECT * FROM users ORDER BY id;")
95    oldquotas = db.query("SELECT * FROM userpquota ORDER BY printerid, userid;")
96   
97    # Fourth close the database
98    db.close()
99    print "Done."
100   
101    # Fifth we delete the old database !
102    answer = raw_input("The old database will be deleted for the upgrade to take place.\nAre you sure you want to continue (y/N) ? ")
103    if answer[0:1].upper() != 'Y' :
104        sys.stderr.write("User wants to stop now ! ABORTED.\n")
105        return -1
106    db = open_database("template1")
107    if db is None :
108        sys.stderr.write("Impossible to connect to database template1. ABORTED.\nPlease report to your Database administrator.\n")
109        return -1
110    try :
111        db.query("DROP DATABASE pykota;")
112    except pg.error, msg :
113        sys.stderr.write("Impossible to delete old database. ABORTED.\n%s\n" % msg)
114        db.close()
115        return -1
116    else :   
117        db.close()
118       
119    # Sixth we create the new database
120    print "Creating the new database...",
121    if not create_new_database() :
122        sys.stderr.write("impossible to create new database ! ABORTED.\n")
123        return -1
124    print "Done."
125   
126    # Seventh we restore old data
127    print "Restoring old datas..."
128    db = open_database()
129    if db is None :
130        sys.stderr.write("Impossible to connect to new PyKota database. ABORTED.\nOld database will be restored if possible.")
131        print "An error occured, I'll try to restore the original database..."
132        if not restore_original_database() :
133            sys.stderr.write("Shit ! A double-error occured !!!\nPlease report problem to your database administrator.\n")
134            sys.stderr.write("And file a bug report to alet@librelogiciel.com\n")
135        else :   
136            print "Done."
137        return -1
138    db.query("BEGIN;")   
139    try :
140        newprinters = {}
141        for oldprinter in oldprinters.dictresult() :
142            db.query("INSERT INTO printers (printername) VALUES (%s);" % doQuote(oldprinter["printername"]))
143            newid = db.query("SELECT id FROM printers WHERE printername='%s';" % oldprinter["printername"]).dictresult()[0]["id"]
144            newprinters[oldprinter["id"]] = newid
145        newusers = {}   
146        for olduser in oldusers.dictresult() :   
147            db.query("INSERT INTO users (username) VALUES (%s);" % doQuote(olduser["username"]))
148            newid = db.query("SELECT id FROM users WHERE username='%s';" % olduser["username"]).dictresult()[0]["id"]
149            newusers[olduser["id"]] = newid
150        for oldquota in oldquotas.dictresult() :   
151            db.query("INSERT INTO userpquota (userid, printerid, pagecounter, lifepagecounter, softlimit, hardlimit, datelimit) VALUES (%s, %s, %s, %s, %s, %s, %s);" % 
152                                              (doQuote(newusers[oldquota["userid"]]) , doQuote(newprinters[oldquota["printerid"]]), doQuote(oldquota["pagecounter"]), doQuote(oldquota["lifepagecounter"]), doQuote(oldquota["softlimit"]), doQuote(oldquota["hardlimit"]), doQuote(oldquota["datelimit"])))
153    except pg.error, msg :   
154        sys.stderr.write("ERROR : %s\nABORTED.\n" % msg)
155        db.query("ROLLBACK;")
156        db.close()   
157        return -1
158    except :   
159        sys.stderr.write("Unknown error ! ABORTED.\n")
160        db.query("ROLLBACK;")
161        db.close()   
162        return -1
163    else :   
164        db.query("COMMIT;")
165        db.close()
166    print "Done."
167    print "NB : Last job on each printer was lost. This is normal !"
168    return 0
169   
170if __name__ == "__main__" :
171    sys.exit(main())
Note: See TracBrowser for help on using the browser.