aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/sabre/dav/bin/migrateto20.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/sabre/dav/bin/migrateto20.php')
-rwxr-xr-xvendor/sabre/dav/bin/migrateto20.php453
1 files changed, 453 insertions, 0 deletions
diff --git a/vendor/sabre/dav/bin/migrateto20.php b/vendor/sabre/dav/bin/migrateto20.php
new file mode 100755
index 000000000..77236804f
--- /dev/null
+++ b/vendor/sabre/dav/bin/migrateto20.php
@@ -0,0 +1,453 @@
+#!/usr/bin/env php
+<?php
+
+echo "SabreDAV migrate script for version 2.0\n";
+
+if ($argc < 2) {
+
+ echo <<<HELLO
+
+This script help you migrate from a pre-2.0 database to 2.0 and later
+
+The 'calendars', 'addressbooks' and 'cards' tables will be upgraded, and new
+tables (calendarchanges, addressbookchanges, propertystorage) will be added.
+
+If you don't use the default PDO CalDAV or CardDAV backend, it's pointless to
+run this script.
+
+Keep in mind that ALTER TABLE commands will be executed. If you have a large
+dataset this may mean that this process takes a while.
+
+Lastly: Make a back-up first. This script has been tested, but the amount of
+potential variants are extremely high, so it's impossible to deal with every
+possible situation.
+
+In the worst case, you will lose all your data. This is not an overstatement.
+
+Usage:
+
+php {$argv[0]} [pdo-dsn] [username] [password]
+
+For example:
+
+php {$argv[0]} "mysql:host=localhost;dbname=sabredav" root password
+php {$argv[0]} sqlite:data/sabredav.db
+
+HELLO;
+
+ exit();
+
+}
+
+// There's a bunch of places where the autoloader could be, so we'll try all of
+// them.
+$paths = [
+ __DIR__ . '/../vendor/autoload.php',
+ __DIR__ . '/../../../autoload.php',
+];
+
+foreach ($paths as $path) {
+ if (file_exists($path)) {
+ include $path;
+ break;
+ }
+}
+
+$dsn = $argv[1];
+$user = isset($argv[2]) ? $argv[2] : null;
+$pass = isset($argv[3]) ? $argv[3] : null;
+
+echo "Connecting to database: " . $dsn . "\n";
+
+$pdo = new PDO($dsn, $user, $pass);
+$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
+
+$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
+
+switch ($driver) {
+
+ case 'mysql' :
+ echo "Detected MySQL.\n";
+ break;
+ case 'sqlite' :
+ echo "Detected SQLite.\n";
+ break;
+ default :
+ echo "Error: unsupported driver: " . $driver . "\n";
+ die(-1);
+}
+
+foreach (['calendar', 'addressbook'] as $itemType) {
+
+ $tableName = $itemType . 's';
+ $tableNameOld = $tableName . '_old';
+ $changesTable = $itemType . 'changes';
+
+ echo "Upgrading '$tableName'\n";
+
+ // The only cross-db way to do this, is to just fetch a single record.
+ $row = $pdo->query("SELECT * FROM $tableName LIMIT 1")->fetch();
+
+ if (!$row) {
+
+ echo "No records were found in the '$tableName' table.\n";
+ echo "\n";
+ echo "We're going to rename the old table to $tableNameOld (just in case).\n";
+ echo "and re-create the new table.\n";
+
+ switch ($driver) {
+
+ case 'mysql' :
+ $pdo->exec("RENAME TABLE $tableName TO $tableNameOld");
+ switch ($itemType) {
+ case 'calendar' :
+ $pdo->exec("
+ CREATE TABLE calendars (
+ id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ principaluri VARCHAR(100),
+ displayname VARCHAR(100),
+ uri VARCHAR(200),
+ synctoken INT(11) UNSIGNED NOT NULL DEFAULT '1',
+ description TEXT,
+ calendarorder INT(11) UNSIGNED NOT NULL DEFAULT '0',
+ calendarcolor VARCHAR(10),
+ timezone TEXT,
+ components VARCHAR(20),
+ transparent TINYINT(1) NOT NULL DEFAULT '0',
+ UNIQUE(principaluri, uri)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+ ");
+ break;
+ case 'addressbook' :
+ $pdo->exec("
+ CREATE TABLE addressbooks (
+ id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ principaluri VARCHAR(255),
+ displayname VARCHAR(255),
+ uri VARCHAR(200),
+ description TEXT,
+ synctoken INT(11) UNSIGNED NOT NULL DEFAULT '1',
+ UNIQUE(principaluri, uri)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+ ");
+ break;
+ }
+ break;
+
+ case 'sqlite' :
+
+ $pdo->exec("ALTER TABLE $tableName RENAME TO $tableNameOld");
+
+ switch ($itemType) {
+ case 'calendar' :
+ $pdo->exec("
+ CREATE TABLE calendars (
+ id integer primary key asc,
+ principaluri text,
+ displayname text,
+ uri text,
+ synctoken integer,
+ description text,
+ calendarorder integer,
+ calendarcolor text,
+ timezone text,
+ components text,
+ transparent bool
+ );
+ ");
+ break;
+ case 'addressbook' :
+ $pdo->exec("
+ CREATE TABLE addressbooks (
+ id integer primary key asc,
+ principaluri text,
+ displayname text,
+ uri text,
+ description text,
+ synctoken integer
+ );
+ ");
+
+ break;
+ }
+ break;
+
+ }
+ echo "Creation of 2.0 $tableName table is complete\n";
+
+ } else {
+
+ // Checking if there's a synctoken field already.
+ if (array_key_exists('synctoken', $row)) {
+ echo "The 'synctoken' field already exists in the $tableName table.\n";
+ echo "It's likely you already upgraded, so we're simply leaving\n";
+ echo "the $tableName table alone\n";
+ } else {
+
+ echo "1.8 table schema detected\n";
+ switch ($driver) {
+
+ case 'mysql' :
+ $pdo->exec("ALTER TABLE $tableName ADD synctoken INT(11) UNSIGNED NOT NULL DEFAULT '1'");
+ $pdo->exec("ALTER TABLE $tableName DROP ctag");
+ $pdo->exec("UPDATE $tableName SET synctoken = '1'");
+ break;
+ case 'sqlite' :
+ $pdo->exec("ALTER TABLE $tableName ADD synctoken integer");
+ $pdo->exec("UPDATE $tableName SET synctoken = '1'");
+ echo "Note: there's no easy way to remove fields in sqlite.\n";
+ echo "The ctag field is no longer used, but it's kept in place\n";
+ break;
+
+ }
+
+ echo "Upgraded '$tableName' to 2.0 schema.\n";
+
+ }
+
+ }
+
+ try {
+ $pdo->query("SELECT * FROM $changesTable LIMIT 1");
+
+ echo "'$changesTable' already exists. Assuming that this part of the\n";
+ echo "upgrade was already completed.\n";
+
+ } catch (Exception $e) {
+ echo "Creating '$changesTable' table.\n";
+
+ switch ($driver) {
+
+ case 'mysql' :
+ $pdo->exec("
+ CREATE TABLE $changesTable (
+ id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ uri VARCHAR(200) NOT NULL,
+ synctoken INT(11) UNSIGNED NOT NULL,
+ {$itemType}id INT(11) UNSIGNED NOT NULL,
+ operation TINYINT(1) NOT NULL,
+ INDEX {$itemType}id_synctoken ({$itemType}id, synctoken)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+ ");
+ break;
+ case 'sqlite' :
+ $pdo->exec("
+
+ CREATE TABLE $changesTable (
+ id integer primary key asc,
+ uri text,
+ synctoken integer,
+ {$itemType}id integer,
+ operation bool
+ );
+
+ ");
+ $pdo->exec("CREATE INDEX {$itemType}id_synctoken ON $changesTable ({$itemType}id, synctoken);");
+ break;
+
+ }
+
+ }
+
+}
+
+try {
+ $pdo->query("SELECT * FROM calendarsubscriptions LIMIT 1");
+
+ echo "'calendarsubscriptions' already exists. Assuming that this part of the\n";
+ echo "upgrade was already completed.\n";
+
+} catch (Exception $e) {
+ echo "Creating calendarsubscriptions table.\n";
+
+ switch ($driver) {
+
+ case 'mysql' :
+ $pdo->exec("
+CREATE TABLE calendarsubscriptions (
+ id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ uri VARCHAR(200) NOT NULL,
+ principaluri VARCHAR(100) NOT NULL,
+ source TEXT,
+ displayname VARCHAR(100),
+ refreshrate VARCHAR(10),
+ calendarorder INT(11) UNSIGNED NOT NULL DEFAULT '0',
+ calendarcolor VARCHAR(10),
+ striptodos TINYINT(1) NULL,
+ stripalarms TINYINT(1) NULL,
+ stripattachments TINYINT(1) NULL,
+ lastmodified INT(11) UNSIGNED,
+ UNIQUE(principaluri, uri)
+);
+ ");
+ break;
+ case 'sqlite' :
+ $pdo->exec("
+
+CREATE TABLE calendarsubscriptions (
+ id integer primary key asc,
+ uri text,
+ principaluri text,
+ source text,
+ displayname text,
+ refreshrate text,
+ calendarorder integer,
+ calendarcolor text,
+ striptodos bool,
+ stripalarms bool,
+ stripattachments bool,
+ lastmodified int
+);
+ ");
+
+ $pdo->exec("CREATE INDEX principaluri_uri ON calendarsubscriptions (principaluri, uri);");
+ break;
+
+ }
+
+}
+
+try {
+ $pdo->query("SELECT * FROM propertystorage LIMIT 1");
+
+ echo "'propertystorage' already exists. Assuming that this part of the\n";
+ echo "upgrade was already completed.\n";
+
+} catch (Exception $e) {
+ echo "Creating propertystorage table.\n";
+
+ switch ($driver) {
+
+ case 'mysql' :
+ $pdo->exec("
+CREATE TABLE propertystorage (
+ id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ path VARBINARY(1024) NOT NULL,
+ name VARBINARY(100) NOT NULL,
+ value MEDIUMBLOB
+);
+ ");
+ $pdo->exec("
+CREATE UNIQUE INDEX path_property ON propertystorage (path(600), name(100));
+ ");
+ break;
+ case 'sqlite' :
+ $pdo->exec("
+CREATE TABLE propertystorage (
+ id integer primary key asc,
+ path TEXT,
+ name TEXT,
+ value TEXT
+);
+ ");
+ $pdo->exec("
+CREATE UNIQUE INDEX path_property ON propertystorage (path, name);
+ ");
+
+ break;
+
+ }
+
+}
+
+echo "Upgrading cards table to 2.0 schema\n";
+
+try {
+
+ $create = false;
+ $row = $pdo->query("SELECT * FROM cards LIMIT 1")->fetch();
+ if (!$row) {
+ $random = mt_rand(1000, 9999);
+ echo "There was no data in the cards table, so we're re-creating it\n";
+ echo "The old table will be renamed to cards_old$random, just in case.\n";
+
+ $create = true;
+
+ switch ($driver) {
+ case 'mysql' :
+ $pdo->exec("RENAME TABLE cards TO cards_old$random");
+ break;
+ case 'sqlite' :
+ $pdo->exec("ALTER TABLE cards RENAME TO cards_old$random");
+ break;
+
+ }
+ }
+
+} catch (Exception $e) {
+
+ echo "Exception while checking cards table. Assuming that the table does not yet exist.\n";
+ echo "Debug: ", $e->getMessage(), "\n";
+ $create = true;
+
+}
+
+if ($create) {
+ switch ($driver) {
+ case 'mysql' :
+ $pdo->exec("
+CREATE TABLE cards (
+ id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ addressbookid INT(11) UNSIGNED NOT NULL,
+ carddata MEDIUMBLOB,
+ uri VARCHAR(200),
+ lastmodified INT(11) UNSIGNED,
+ etag VARBINARY(32),
+ size INT(11) UNSIGNED NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+ ");
+ break;
+
+ case 'sqlite' :
+
+ $pdo->exec("
+CREATE TABLE cards (
+ id integer primary key asc,
+ addressbookid integer,
+ carddata blob,
+ uri text,
+ lastmodified integer,
+ etag text,
+ size integer
+);
+ ");
+ break;
+
+ }
+} else {
+ switch ($driver) {
+ case 'mysql' :
+ $pdo->exec("
+ ALTER TABLE cards
+ ADD etag VARBINARY(32),
+ ADD size INT(11) UNSIGNED NOT NULL;
+ ");
+ break;
+
+ case 'sqlite' :
+
+ $pdo->exec("
+ ALTER TABLE cards ADD etag text;
+ ALTER TABLE cards ADD size integer;
+ ");
+ break;
+
+ }
+ echo "Reading all old vcards and populating etag and size fields.\n";
+ $result = $pdo->query('SELECT id, carddata FROM cards');
+ $stmt = $pdo->prepare('UPDATE cards SET etag = ?, size = ? WHERE id = ?');
+ while ($row = $result->fetch(\PDO::FETCH_ASSOC)) {
+ $stmt->execute([
+ md5($row['carddata']),
+ strlen($row['carddata']),
+ $row['id']
+ ]);
+ }
+
+
+}
+
+echo "Upgrade to 2.0 schema completed.\n";