import
[web.mtrack] / bin / schema-tool.php
1 <?php # vim:ts=2:sw=2:et:
2 /* For licensing and copyright terms, see the file named LICENSE */
3
4 if (function_exists('date_default_timezone_set')) {
5   date_default_timezone_set('UTC');
6 }
7 ini_set('memory_limit', -1);
8
9 include_once dirname(__FILE__) . '/../inc/common.php';
10
11 $dsn = 'sqlite::memory:';
12 #$dsn = 'pgsql:dbname=wez';
13
14 $dsn = MTrackConfig::get('core', 'dsn');
15 if (!$dsn) {
16   $dsn = 'sqlite:' . MTrackConfig::get('core', 'dblocation');
17 }
18
19 if (preg_match("/^sqlite:(.*)$/", $dsn, $M)) {
20   $dbfile = $M[1];
21   if (file_exists($dbfile)) {
22     $bak = $dbfile . '.' . uniqid();
23     echo "Backing up $dbfile as $bak\n";
24     copy($dbfile, $bak);
25   }
26 }
27
28 $db = new PDO($dsn);
29 $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
30
31 $driver = $db->getAttribute(PDO::ATTR_DRIVER_NAME);
32 $adapter_class = "MTrackDBSchema_$driver";
33 $adapter = new $adapter_class;
34
35 $adapter->setDB($db);
36 $vers = $adapter->determineVersion();
37 echo "Version: ";
38 var_dump($vers);
39
40 $db->beginTransaction();
41 MTrackDB::$db = $db;
42
43 $schemata = array();
44 $latest = null;
45 foreach (glob(dirname(__FILE__) . '/../schema/*.xml') as $filename) {
46   $latest = new MTrackDBSchema($filename);
47   $schemata[$latest->version] = $latest;
48 }
49
50 if ($vers === null) {
51
52   if (true) {
53     // Fresh install
54     echo "Applying schema version $latest->version\n";
55
56     foreach ($latest->tables as $t) {
57       $adapter->createTable($t);
58     }
59     if (isset($latest->post[$driver])) {
60       $db->exec($latest->post[$driver]);
61     }
62
63     $vers = $latest->version;
64
65   } else {
66     // while developing, make it go through the whole migration
67     $initial = $schemata[0];
68     echo "Applying schema version $initial->version\n";
69
70     foreach ($initial->tables as $t) {
71       $adapter->createTable($t);
72     }
73     $vers = 0;
74   }
75 }
76
77 while ($vers < $latest->version) {
78   $current = $schemata[$vers];
79   $next = $schemata[$vers+1];
80
81   echo "Applying migration from schema version $current->version to $next->version\n";
82
83   $migration = dirname(__FILE__) . "/../schema/$next->version-pre.php";
84   if (file_exists($migration)) {
85     echo "Running migration script schema/$next->version-pre.php\n";
86     include $migration;
87   }
88
89   /* create any new tables */
90   foreach ($next->tables as $t) {
91     if (isset($current->tables[$t->name])) continue;
92     /* doesn't yet exist, so create it! */
93     $adapter->createTable($t);
94   }
95
96   /* modify existing tables */
97   foreach ($current->tables as $t) {
98     if (!isset($next->tables[$t->name])) continue;
99
100     $nt = $next->tables[$t->name];
101     /* compare; have they changed? */
102     if (!$t->sameAs($nt)) {
103       $adapter->alterTable($t, $nt);
104     }
105   }
106
107   /* delete dead tables */
108   foreach ($current->tables as $t) {
109     if (isset($next->tables[$t->name])) continue;
110     $adapter->dropTable($t);
111   }
112
113   $vers++;
114
115   if (isset($next->post[$driver])) {
116     $db->exec($next->post[$driver]);
117   }
118
119   $migration = dirname(__FILE__) . "/../schema/$vers.php";
120   if (file_exists($migration)) {
121     echo "Running migration script schema/$vers.php\n";
122     include $migration;
123   }
124 }
125
126 $db->exec('delete from mtrack_schema');
127 $q = $db->prepare('insert into mtrack_schema (version) values (?)');
128 $q->execute(array($latest->version));
129 $db->commit();
130
131