This commit was generated by cvs2svn to compensate for changes in r8690,
[freeside.git] / FS / bin / freeside-upgrade
1 #!/usr/bin/perl -w
2
3 use strict;
4 use vars qw($opt_d $opt_s $opt_q $opt_v $opt_r);
5 use vars qw($DEBUG $DRY_RUN);
6 use Getopt::Std;
7 use DBIx::DBSchema 0.31;
8 use FS::UID qw(adminsuidsetup checkeuid datasrc driver_name);  #getsecrets);
9 use FS::CurrentUser;
10 use FS::Schema qw( dbdef dbdef_dist reload_dbdef );
11 use FS::Misc::prune qw(prune_applications);
12 use FS::Conf;
13 use FS::Record qw(qsearch);
14 use FS::Upgrade qw(upgrade upgrade_sqlradius);
15
16 my $start = time;
17
18 die "Not running uid freeside!" unless checkeuid();
19
20 getopts("dqrs");
21
22 $DEBUG = !$opt_q;
23 #$DEBUG = $opt_v;
24
25 $DRY_RUN = $opt_d;
26
27 my $user = shift or die &usage;
28 $FS::CurrentUser::upgrade_hack = 1;
29 $FS::UID::callback_hack = 1;
30 my $dbh = adminsuidsetup($user);
31 $FS::UID::callback_hack = 0;
32
33 #needs to match FS::Schema...
34 my $dbdef_file = "%%%FREESIDE_CONF%%%/dbdef.". datasrc;
35
36 dbdef_create($dbh, $dbdef_file);
37
38 delete $FS::Schema::dbdef_cache{$dbdef_file}; #force an actual reload
39 reload_dbdef($dbdef_file);
40
41 warn "Upgrade startup completed in ". (time-$start). " seconds\n"; # if $DEBUG;
42 $start = time;
43
44 #$DBIx::DBSchema::DEBUG = $DEBUG;
45 #$DBIx::DBSchema::Table::DEBUG = $DEBUG;
46 #$DBIx::DBSchema::Index::DEBUG = $DEBUG;
47
48 my @bugfix = ();
49
50 if (dbdef->table('cust_main')->column('agent_custid') && ! $opt_s) { 
51   push @bugfix,
52     "UPDATE cust_main SET agent_custid = NULL where agent_custid = ''";
53
54   push @bugfix,
55     "UPDATE h_cust_main SET agent_custid = NULL where agent_custid = ''"
56       if (dbdef->table('h_cust_main')); 
57 }
58
59 #you should have run fs-migrate-part_svc ages ago, when you upgraded
60 #from 1.3 to 1.4... if not, it needs to be hooked into -upgrade here or
61 #you'll lose all the part_svc settings it migrates to part_svc_column
62
63 my @statements =
64   grep { $_ !~ /^CREATE +INDEX +h_queue/i } #useless, holds up queue insertion
65        dbdef->sql_update_schema( dbdef_dist(datasrc), $dbh );
66
67 unless ( driver_name =~ /^mysql/i ) {
68   #not necessary under non-mysql, takes forever on big db
69   @statements =
70     grep { $_ !~ /^ *ALTER +TABLE +h_queue +ALTER +COLUMN +job +TYPE +varchar\(512\) *$/i }
71          @statements;
72 }
73
74 if ( $DRY_RUN ) {
75   print
76     join(";\n", @bugfix, @statements ). ";\n";
77   exit;
78 } else {
79   foreach my $statement ( @bugfix, @statements ) {
80     warn "$statement\n";
81     $dbh->do( $statement )
82       or die "Error: ". $dbh->errstr. "\n executing: $statement";
83   }
84
85 #  warn "Pre-schema change upgrades completed in ". (time-$start). " seconds\n"; # if $DEBUG;
86 #  $start = time;
87
88 #  dbdef->update_schema( dbdef_dist(datasrc), $dbh );
89 }
90
91 warn "Schema upgrade completed in ". (time-$start). " seconds\n"; # if $DEBUG;
92 $start = time;
93
94 my $hashref = {};
95 $hashref->{dry_run} = 1 if $DRY_RUN;
96 $hashref->{debug} = 1 if $DEBUG && $DRY_RUN;
97 prune_applications($hashref) unless $opt_s;
98
99 warn "Application pruning completed in ". (time-$start). " seconds\n"; # if $DEBUG;
100 $start = time;
101
102 print "\n" if $DRY_RUN;
103
104 if ( $dbh->{Driver}->{Name} =~ /^mysql/i && ! $opt_s ) {
105
106   foreach my $table (qw( svc_acct svc_phone )) {
107
108     my $sth = $dbh->prepare(
109       "SELECT COUNT(*) FROM duplicate_lock WHERE lockname = '$table'"
110     ) or die $dbh->errstr;
111
112     $sth->execute or die $sth->errstr;
113
114     unless ( $sth->fetchrow_arrayref->[0] ) {
115
116       $sth = $dbh->prepare(
117         "INSERT INTO duplicate_lock ( lockname ) VALUES ( '$table' )"
118       ) or die $dbh->errstr;
119
120       $sth->execute or die $sth->errstr;
121
122     }
123
124   }
125
126   warn "Duplication lock creation completed in ". (time-$start). " seconds\n"; # if $DEBUG;
127   $start = time;
128
129 }
130
131 $dbh->commit or die $dbh->errstr;
132
133 dbdef_create($dbh, $dbdef_file);
134
135 $dbh->disconnect or die $dbh->errstr;
136
137 delete $FS::Schema::dbdef_cache{$dbdef_file}; #force an actual reload
138 $FS::UID::AutoCommit = 0;
139 $FS::UID::callback_hack = 1;
140 $dbh = adminsuidsetup($user);
141 $FS::UID::callback_hack = 0;
142 unless ( $DRY_RUN || $opt_s ) {
143   my $dir = "%%%FREESIDE_CONF%%%/conf.". datasrc;
144   if (!scalar(qsearch('conf', {}))) {
145     my $error = FS::Conf::init_config($dir);
146     if ($error) {
147       warn "CONFIGURATION UPGRADE FAILED\n";
148       $dbh->rollback or die $dbh->errstr;
149       die $error;
150     }
151   }
152 }
153 $dbh->commit or die $dbh->errstr;
154 $dbh->disconnect or die $dbh->errstr;
155
156 $dbh = adminsuidsetup($user);
157
158 warn "Re-initialization with updated schema completed in ". (time-$start). " seconds\n"; # if $DEBUG;
159 $start = time;
160
161 upgrade()
162   unless $DRY_RUN || $opt_s;
163
164 $dbh->commit or die $dbh->errstr;
165
166 warn "Table updates completed in ". (time-$start). " seconds\n"; # if $DEBUG;
167 $start = time;
168
169 upgrade_sqlradius()
170   unless $DRY_RUN || $opt_s || $opt_r;
171
172 warn "SQL RADIUS updates completed in ". (time-$start). " seconds\n"; # if $DEBUG;
173 $start = time;
174
175 $dbh->commit or die $dbh->errstr;
176 $dbh->disconnect or die $dbh->errstr;
177
178 warn "Final commit and disconnection completed in ". (time-$start). " seconds; upgrade done!\n"; # if $DEBUG;
179
180 ###
181
182 sub dbdef_create { # reverse engineer the schema from the DB and save to file
183   my( $dbh, $file ) = @_;
184   my $dbdef = new_native DBIx::DBSchema $dbh;
185   $dbdef->save($file);
186 }
187
188 sub usage {
189   die "Usage:\n  freeside-upgrade [ -d ] [ -r ] [ -s ] [ -q | -v ] user\n"; 
190 }
191
192 =head1 NAME
193
194 freeside-upgrade - Upgrades database schema for new freeside verisons.
195
196 =head1 SYNOPSIS
197
198   freeside-upgrade [ -d ] [ -r ] [ -s ] [ -q | -v ]
199
200 =head1 DESCRIPTION
201
202 Reads your existing database schema and updates it to match the current schema,
203 adding any columns or tables necessary.
204
205 Also performs other upgrade functions:
206
207 =over 4
208
209 =item Calls FS:: Misc::prune::prune_applications (probably unnecessary every upgrade, but simply won't find any records to change)
210
211 =item If necessary, moves your configuration information from the filesystem in /usr/local/etc/freeside/conf.<datasrc> to the database.
212
213 =back
214
215   [ -d ]: Dry run; output SQL statements (to STDOUT) only, but do not execute
216           them.
217
218   [ -q ]: Run quietly.  This may become the default at some point.
219
220   [ -r ]: Skip sqlradius updates.  Useful for occassions where the sqlradius
221           databases may be inaccessible.
222
223   [ -v ]: Run verbosely, sending debugging information to STDERR.  This is the
224           current default.
225
226   [ -s ]: Schema changes only.  Useful for Pg/slony slaves where the data
227           changes will be replicated from the Pg/slony master.
228
229 =head1 SEE ALSO
230
231 =cut
232