finish mysql locking workaround
[freeside.git] / FS / bin / freeside-upgrade
1 #!/usr/bin/perl -w
2
3 use strict;
4 use vars qw($opt_d $opt_q $opt_v);
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 );  #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
15 die "Not running uid freeside!" unless checkeuid();
16
17 getopts("dq");
18
19 $DEBUG = !$opt_q;
20 #$DEBUG = $opt_v;
21
22 $DRY_RUN = $opt_d;
23
24 my $user = shift or die &usage;
25 $FS::CurrentUser::upgrade_hack = 1;
26 $FS::UID::callback_hack = 1;
27 my $dbh = adminsuidsetup($user);
28 $FS::UID::callback_hack = 0;
29
30 #needs to match FS::Schema...
31 my $dbdef_file = "%%%FREESIDE_CONF%%%/dbdef.". datasrc;
32
33 dbdef_create($dbh, $dbdef_file);
34
35 delete $FS::Schema::dbdef_cache{$dbdef_file}; #force an actual reload
36 reload_dbdef($dbdef_file);
37
38 $DBIx::DBSchema::DEBUG = $DEBUG;
39 $DBIx::DBSchema::Table::DEBUG = $DEBUG;
40 $DBIx::DBSchema::Index::DEBUG = $DEBUG;
41
42 my @bugfix = ();
43
44 if (dbdef->table('cust_main')->column('agent_custid')) { 
45   push @bugfix,
46     "UPDATE cust_main SET agent_custid = NULL where agent_custid = ''";
47
48   push @bugfix,
49     "UPDATE h_cust_main SET agent_custid = NULL where agent_custid = ''"
50       if (dbdef->table('h_cust_main')); 
51 }
52
53 #you should have run fs-migrate-part_svc ages ago, when you upgraded
54 #from 1.3 to 1.4... if not, it needs to be hooked into -upgrade here or
55 #you'll lose all the part_svc settings it migrates to part_svc_column
56
57 if ( $DRY_RUN ) {
58   print
59     join(";\n", @bugfix, dbdef->sql_update_schema( dbdef_dist(datasrc), $dbh ) ). ";\n";
60   exit;
61 } else {
62   foreach my $statement ( @bugfix ) {
63     $dbh->do( $statement )
64       or die "Error: ". $dbh->errstr. "\n executing: $statement";
65   }
66
67   dbdef->update_schema( dbdef_dist(datasrc), $dbh );
68 }
69
70 my $hashref = {};
71 $hashref->{dry_run} = 1 if $DRY_RUN;
72 $hashref->{debug} = 1 if $DEBUG;
73 print join "\n", prune_applications($hashref);
74 print "\n" if $DRY_RUN;
75
76 if ( $dbh->{Driver}->{Name} =~ /^mysql/i ) {
77
78   my $sth = $dbh->prepare(
79     "SELECT COUNT(*) FROM duplicate_lock WHERE lockname = 'svc_acct'"
80   ) or die $dbh->errstr;
81
82   $sth->execute or die $sth->errstr;
83
84   unless ( $sth->fetchrow_arrayref->[0] ) {
85
86     $sth = $dbh->prepare(
87       "INSERT INTO duplicate_lock ( lockname ) VALUES ( 'svc_acct' )"
88     ) or die $dbh->errstr;
89
90     $sth->execute or die $sth->errstr;
91
92   }
93 }
94
95 $dbh->commit or die $dbh->errstr;
96
97 dbdef_create($dbh, $dbdef_file);
98
99 $dbh->disconnect or die $dbh->errstr;
100
101 delete $FS::Schema::dbdef_cache{$dbdef_file}; #force an actual reload
102 $FS::UID::AutoCommit = 1;
103 $FS::UID::callback_hack = 1;
104 $dbh = adminsuidsetup($user);
105 $FS::UID::callback_hack = 0;
106 unless ( $DRY_RUN ) {
107   my $dir = "%%%FREESIDE_CONF%%%/conf.". datasrc;
108   if (!scalar(qsearch('conf', {}))) {
109     my $error = FS::Conf::init_config($dir);
110     if ($error) {
111       warn "CONFIGURATION UPGRADE FAILED\n";
112       $dbh->rollback or die $dbh->errstr;
113       die $error;
114     }
115   }
116 }
117 $dbh->commit or die $dbh->errstr;
118 $dbh->disconnect or die $dbh->errstr;
119
120 ###
121
122 sub dbdef_create { # reverse engineer the schema from the DB and save to file
123   my( $dbh, $file ) = @_;
124   my $dbdef = new_native DBIx::DBSchema $dbh;
125   $dbdef->save($file);
126 }
127
128 sub usage {
129   die "Usage:\n  freeside-upgrade [ -d ] [ -q | -v ] user\n"; 
130 }
131
132 =head1 NAME
133
134 freeside-upgrade - Upgrades database schema for new freeside verisons.
135
136 =head1 SYNOPSIS
137
138   freeside-upgrade [ -d ] [ -q | -v ]
139
140 =head1 DESCRIPTION
141
142 Reads your existing database schema and updates it to match the current schema,
143 adding any columns or tables necessary.
144
145 Also performs other upgrade functions:
146
147 =over 4
148
149 =item Calls FS:: Misc::prune::prune_applications (probably unnecessary every upgrade, but simply won't find any records to change)
150
151 =item If necessary, moves your configuration information from the filesystem in /usr/local/etc/freeside/conf.<datasrc> to the database.
152
153 =back
154
155   [ -d ]: Dry run; output SQL statements (to STDOUT) only, but do not execute
156           them.
157
158   [ -q ]: Run quietly.  This may become the default at some point.
159
160   [ -v ]: Run verbosely, sending debugging information to STDERR.  This is the
161           current default.
162
163 =head1 SEE ALSO
164
165 =cut
166