xref: /plugin/davcal/vendor/sabre/dav/bin/migrateto30.php (revision a1a3b6794e0e143a4a8b51d3185ce2d339be61ab)
1*a1a3b679SAndreas Boehler#!/usr/bin/env php
2*a1a3b679SAndreas Boehler<?php
3*a1a3b679SAndreas Boehler
4*a1a3b679SAndreas Boehlerecho "SabreDAV migrate script for version 3.0\n";
5*a1a3b679SAndreas Boehler
6*a1a3b679SAndreas Boehlerif ($argc<2) {
7*a1a3b679SAndreas Boehler
8*a1a3b679SAndreas Boehler    echo <<<HELLO
9*a1a3b679SAndreas Boehler
10*a1a3b679SAndreas BoehlerThis script help you migrate from a pre-3.0 database to 3.0 and later
11*a1a3b679SAndreas Boehler
12*a1a3b679SAndreas BoehlerChanges:
13*a1a3b679SAndreas Boehler  * The propertystorage table has changed to allow storage of complex
14*a1a3b679SAndreas Boehler    properties.
15*a1a3b679SAndreas Boehler  * the vcardurl field in the principals table is no more. This was moved to
16*a1a3b679SAndreas Boehler    the propertystorage table.
17*a1a3b679SAndreas Boehler
18*a1a3b679SAndreas BoehlerKeep in mind that ALTER TABLE commands will be executed. If you have a large
19*a1a3b679SAndreas Boehlerdataset this may mean that this process takes a while.
20*a1a3b679SAndreas Boehler
21*a1a3b679SAndreas BoehlerLastly: Make a back-up first. This script has been tested, but the amount of
22*a1a3b679SAndreas Boehlerpotential variants are extremely high, so it's impossible to deal with every
23*a1a3b679SAndreas Boehlerpossible situation.
24*a1a3b679SAndreas Boehler
25*a1a3b679SAndreas BoehlerIn the worst case, you will lose all your data. This is not an overstatement.
26*a1a3b679SAndreas Boehler
27*a1a3b679SAndreas BoehlerUsage:
28*a1a3b679SAndreas Boehler
29*a1a3b679SAndreas Boehlerphp {$argv[0]} [pdo-dsn] [username] [password]
30*a1a3b679SAndreas Boehler
31*a1a3b679SAndreas BoehlerFor example:
32*a1a3b679SAndreas Boehler
33*a1a3b679SAndreas Boehlerphp {$argv[0]} "mysql:host=localhost;dbname=sabredav" root password
34*a1a3b679SAndreas Boehlerphp {$argv[0]} sqlite:data/sabredav.db
35*a1a3b679SAndreas Boehler
36*a1a3b679SAndreas BoehlerHELLO;
37*a1a3b679SAndreas Boehler
38*a1a3b679SAndreas Boehler    exit();
39*a1a3b679SAndreas Boehler
40*a1a3b679SAndreas Boehler}
41*a1a3b679SAndreas Boehler
42*a1a3b679SAndreas Boehler// There's a bunch of places where the autoloader could be, so we'll try all of
43*a1a3b679SAndreas Boehler// them.
44*a1a3b679SAndreas Boehler$paths = [
45*a1a3b679SAndreas Boehler    __DIR__ . '/../vendor/autoload.php',
46*a1a3b679SAndreas Boehler    __DIR__ . '/../../../autoload.php',
47*a1a3b679SAndreas Boehler];
48*a1a3b679SAndreas Boehler
49*a1a3b679SAndreas Boehlerforeach($paths as $path) {
50*a1a3b679SAndreas Boehler    if (file_exists($path)) {
51*a1a3b679SAndreas Boehler        include $path;
52*a1a3b679SAndreas Boehler        break;
53*a1a3b679SAndreas Boehler    }
54*a1a3b679SAndreas Boehler}
55*a1a3b679SAndreas Boehler
56*a1a3b679SAndreas Boehler$dsn = $argv[1];
57*a1a3b679SAndreas Boehler$user = isset($argv[2])?$argv[2]:null;
58*a1a3b679SAndreas Boehler$pass = isset($argv[3])?$argv[3]:null;
59*a1a3b679SAndreas Boehler
60*a1a3b679SAndreas Boehlerecho "Connecting to database: " . $dsn . "\n";
61*a1a3b679SAndreas Boehler
62*a1a3b679SAndreas Boehler$pdo = new PDO($dsn, $user, $pass);
63*a1a3b679SAndreas Boehler$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
64*a1a3b679SAndreas Boehler$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
65*a1a3b679SAndreas Boehler
66*a1a3b679SAndreas Boehler$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
67*a1a3b679SAndreas Boehler
68*a1a3b679SAndreas Boehlerswitch($driver) {
69*a1a3b679SAndreas Boehler
70*a1a3b679SAndreas Boehler    case 'mysql' :
71*a1a3b679SAndreas Boehler        echo "Detected MySQL.\n";
72*a1a3b679SAndreas Boehler        break;
73*a1a3b679SAndreas Boehler    case 'sqlite' :
74*a1a3b679SAndreas Boehler        echo "Detected SQLite.\n";
75*a1a3b679SAndreas Boehler        break;
76*a1a3b679SAndreas Boehler    default :
77*a1a3b679SAndreas Boehler        echo "Error: unsupported driver: " . $driver . "\n";
78*a1a3b679SAndreas Boehler        die(-1);
79*a1a3b679SAndreas Boehler}
80*a1a3b679SAndreas Boehler
81*a1a3b679SAndreas Boehlerecho "Upgrading 'propertystorage'\n";
82*a1a3b679SAndreas Boehler$addValueType = false;
83*a1a3b679SAndreas Boehlertry {
84*a1a3b679SAndreas Boehler    $result = $pdo->query('SELECT * FROM propertystorage LIMIT 1');
85*a1a3b679SAndreas Boehler    $row = $result->fetch(\PDO::FETCH_ASSOC);
86*a1a3b679SAndreas Boehler
87*a1a3b679SAndreas Boehler    if (!$row) {
88*a1a3b679SAndreas Boehler        echo "No data in table. Going to re-create the table.\n";
89*a1a3b679SAndreas Boehler        $random = mt_rand(1000,9999);
90*a1a3b679SAndreas Boehler        echo "Renaming propertystorage -> propertystorage_old$random and creating new table.\n";
91*a1a3b679SAndreas Boehler
92*a1a3b679SAndreas Boehler        switch($driver) {
93*a1a3b679SAndreas Boehler
94*a1a3b679SAndreas Boehler            case 'mysql' :
95*a1a3b679SAndreas Boehler                $pdo->exec('RENAME TABLE propertystorage TO propertystorage_old' . $random);
96*a1a3b679SAndreas Boehler                $pdo->exec('
97*a1a3b679SAndreas Boehler    CREATE TABLE propertystorage (
98*a1a3b679SAndreas Boehler        id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
99*a1a3b679SAndreas Boehler        path VARBINARY(1024) NOT NULL,
100*a1a3b679SAndreas Boehler        name VARBINARY(100) NOT NULL,
101*a1a3b679SAndreas Boehler        valuetype INT UNSIGNED,
102*a1a3b679SAndreas Boehler        value MEDIUMBLOB
103*a1a3b679SAndreas Boehler    );
104*a1a3b679SAndreas Boehler                ');
105*a1a3b679SAndreas Boehler                $pdo->exec('CREATE UNIQUE INDEX path_property_' . $random . '  ON propertystorage (path(600), name(100));');
106*a1a3b679SAndreas Boehler                break;
107*a1a3b679SAndreas Boehler            case 'sqlite' :
108*a1a3b679SAndreas Boehler                $pdo->exec('ALTER TABLE propertystorage RENAME TO propertystorage_old' . $random);
109*a1a3b679SAndreas Boehler                $pdo->exec('
110*a1a3b679SAndreas BoehlerCREATE TABLE propertystorage (
111*a1a3b679SAndreas Boehler    id integer primary key asc,
112*a1a3b679SAndreas Boehler    path text,
113*a1a3b679SAndreas Boehler    name text,
114*a1a3b679SAndreas Boehler    valuetype integer,
115*a1a3b679SAndreas Boehler    value blob
116*a1a3b679SAndreas Boehler);');
117*a1a3b679SAndreas Boehler
118*a1a3b679SAndreas Boehler                $pdo->exec('CREATE UNIQUE INDEX path_property_' . $random . ' ON propertystorage (path, name);');
119*a1a3b679SAndreas Boehler                break;
120*a1a3b679SAndreas Boehler
121*a1a3b679SAndreas Boehler        }
122*a1a3b679SAndreas Boehler    } elseif (array_key_exists('valuetype', $row)) {
123*a1a3b679SAndreas Boehler        echo "valuetype field exists. Assuming that this part of the migration has\n";
124*a1a3b679SAndreas Boehler        echo "Already been completed.\n";
125*a1a3b679SAndreas Boehler    } else {
126*a1a3b679SAndreas Boehler        echo "2.1 schema detected. Going to perform upgrade.\n";
127*a1a3b679SAndreas Boehler        $addValueType = true;
128*a1a3b679SAndreas Boehler    }
129*a1a3b679SAndreas Boehler
130*a1a3b679SAndreas Boehler} catch (Exception $e) {
131*a1a3b679SAndreas Boehler    echo "Could not find a propertystorage table. Skipping this part of the\n";
132*a1a3b679SAndreas Boehler    echo "upgrade.\n";
133*a1a3b679SAndreas Boehler    echo $e->getMessage(), "\n";
134*a1a3b679SAndreas Boehler}
135*a1a3b679SAndreas Boehler
136*a1a3b679SAndreas Boehlerif ($addValueType) {
137*a1a3b679SAndreas Boehler
138*a1a3b679SAndreas Boehler    switch($driver) {
139*a1a3b679SAndreas Boehler        case 'mysql' :
140*a1a3b679SAndreas Boehler            $pdo->exec('ALTER TABLE propertystorage ADD valuetype INT UNSIGNED');
141*a1a3b679SAndreas Boehler            break;
142*a1a3b679SAndreas Boehler        case 'sqlite' :
143*a1a3b679SAndreas Boehler            $pdo->exec('ALTER TABLE propertystorage ADD valuetype INT');
144*a1a3b679SAndreas Boehler
145*a1a3b679SAndreas Boehler            break;
146*a1a3b679SAndreas Boehler    }
147*a1a3b679SAndreas Boehler
148*a1a3b679SAndreas Boehler    $pdo->exec('UPDATE propertystorage SET valuetype = 1 WHERE valuetype IS NULL ');
149*a1a3b679SAndreas Boehler
150*a1a3b679SAndreas Boehler}
151*a1a3b679SAndreas Boehler
152*a1a3b679SAndreas Boehlerecho "Migrating vcardurl\n";
153*a1a3b679SAndreas Boehler
154*a1a3b679SAndreas Boehler$result = $pdo->query('SELECT id, uri, vcardurl FROM principals WHERE vcardurl IS NOT NULL');
155*a1a3b679SAndreas Boehler$stmt1 = $pdo->prepare('INSERT INTO propertystorage (path, name, valuetype, value) VALUES (?, ?, 3, ?)');
156*a1a3b679SAndreas Boehler
157*a1a3b679SAndreas Boehlerwhile($row = $result->fetch(\PDO::FETCH_ASSOC)) {
158*a1a3b679SAndreas Boehler
159*a1a3b679SAndreas Boehler    // Inserting the new record
160*a1a3b679SAndreas Boehler    $stmt1->execute([
161*a1a3b679SAndreas Boehler        'addressbooks/' . basename($row['uri']),
162*a1a3b679SAndreas Boehler        '{http://calendarserver.org/ns/}me-card',
163*a1a3b679SAndreas Boehler        serialize(new Sabre\DAV\Xml\Property\Href($row['vcardurl']))
164*a1a3b679SAndreas Boehler    ]);
165*a1a3b679SAndreas Boehler
166*a1a3b679SAndreas Boehler    echo serialize(new Sabre\DAV\Xml\Property\Href($row['vcardurl']));
167*a1a3b679SAndreas Boehler
168*a1a3b679SAndreas Boehler}
169*a1a3b679SAndreas Boehler
170*a1a3b679SAndreas Boehlerecho "Done.\n";
171*a1a3b679SAndreas Boehlerecho "Upgrade to 3.0 schema completed.\n";
172