]> git.decadent.org.uk Git - dak.git/blob - dak/update_db.py
Added update system for the database, and the first update script
[dak.git] / dak / update_db.py
1 #!/usr/bin/env python
2
3 # Debian Archive Kit Database Update Script
4 # Copyright (C) 2008  Michael Casadevall <mcasadevall@debian.org>
5
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20 ################################################################################
21
22 # <Ganneff> when do you have it written?
23 # <NCommander> Ganneff, after you make my debian account
24 # <Ganneff> blackmail wont work
25 # <NCommander> damn it
26
27 ################################################################################
28
29 import psycopg2, sys
30 import apt_pkg
31 import time
32 from daklib import database
33 from daklib import utils
34
35 ################################################################################
36
37 Cnf = None
38 projectB = None
39 required_database_schema = 1
40
41 ################################################################################
42
43 class UpdateDB:
44     def usage (self, exit_code=0):
45         print """Usage: dak update-db
46 Updates dak's database schema to the lastest version. You should disable crontabs while this is running
47
48   -h, --help                show this help and exit."""
49         sys.exit(exit_code)
50
51
52 ################################################################################
53     def update_db_to_zero(self):
54         # This function will attempt to update a pre-zero database schema to zero
55
56         # First, do the sure thing, and create the configuration table
57         try:
58             print "Creating configuration table ..."
59             c = self.db.cursor()
60             c.execute("""CREATE TABLE config (
61                                   id SERIAL PRIMARY KEY NOT NULL,
62                                   name TEXT UNIQUE NOT NULL,
63                                   value TEXT
64                                 );""")
65             c.execute("INSERT INTO config VALUES ( nextval('config_id_seq'), 'db_revision', '0')");
66             self.db.commit()
67
68         except psycopg2.ProgrammingError:
69             self.db.rollback()
70             print "Failed to create configuration table."
71             print "Can the projectB user CREATE TABLE?"
72             print ""
73             print "Aborting update."
74             sys.exit(-255)
75
76 ################################################################################
77
78     def get_db_rev(self):
79         global projectB
80
81         # We keep database revision info the config table
82         # Try and access it
83
84         try:
85             c = self.db.cursor()
86             q = c.execute("SELECT value FROM config WHERE name = 'db_revision';");
87             return c.fetchone()[0]
88
89         except psycopg2.ProgrammingError:
90             # Whoops .. no config table ...
91             self.db.rollback()
92             print "No configuration table found, assuming dak database revision to be pre-zero"
93             return -1
94
95 ################################################################################
96
97     def update_db(self):
98         # Ok, try and find the configuration table
99         print "Determining dak database revision ..."
100
101         try:
102             self.db = psycopg2.connect("dbname='" + Cnf["DB::Name"] + "' host='" + Cnf["DB::Host"] + "' port='" + str(Cnf["DB::Port"]) + "'")
103
104         except:
105             print "FATAL: Failed connect to database"
106             pass
107
108         database_revision = int(self.get_db_rev())
109
110         if database_revision == -1:
111             print "dak database schema predates update-db."
112             print ""
113             print "This script will attempt to upgrade it to the lastest, but may fail."
114             print "Please make sure you have a database backup handy. If you don't, press Ctrl-C now!"
115             print ""
116             print "Continuing in five seconds ..."
117             #time.sleep(5)
118             print ""
119             print "Attempting to upgrade pre-zero database to zero"
120
121             self.update_db_to_zero()
122             database_revision = 0
123
124         print "dak database schema at " + str(database_revision)
125         print "dak version requires schema " + str(required_database_schema)
126
127         if database_revision == required_database_schema:
128             print "no updates required"
129             sys.exit(0)
130
131         for i in range (database_revision, required_database_schema):
132             print "updating databse schema from " + str(database_revision) + " to " + str(i+1)
133             dakdb = __import__("dakdb", globals(), locals(), ['update'+str(i+1)])
134             update_module = getattr(dakdb, "update"+str(i+1))
135             update_module.do_update(self)
136             database_revision /+ 1
137
138 ################################################################################
139
140     def init (self):
141         global Cnf, projectB
142
143         Cnf = utils.get_conf()
144         arguments = [('h', "help", "Update-DB::Options::Help")]
145         for i in [ "help" ]:
146             if not Cnf.has_key("Update-DB::Options::%s" % (i)):
147                 Cnf["Update-DB::Options::%s" % (i)] = ""
148
149         arguments = apt_pkg.ParseCommandLine(Cnf, arguments, sys.argv)
150
151         options = Cnf.SubTree("Update-DB::Options")
152         if options["Help"]:
153             usage()
154         elif arguments:
155             utils.warn("dak update-db takes no arguments.")
156             usage(exit_code=1)
157
158         self.update_db()
159
160 ################################################################################
161
162 if __name__ == '__main__':
163     app = UpdateDB()
164     app.init()
165
166 def main():
167     app = UpdateDB()
168     app.init()