#!/usr/bin/env php null, 'u' => null, 'p' => null, ); if ($options['v'] && !is_numeric($options['v'])) { usage(); } echo phutil_console_wrap( "Before running this script, you should take down the Phabricator web ". "interface and stop any running Phabricator daemons."); if (!phutil_console_confirm('Are you ready to continue?')) { echo "Cancelled.\n"; exit(1); } // Use always the version from the commandline if it is defined $next_version = isset($options['v']) ? (int)$options['v'] : null; if ($options['u']) { $conn_user = $options['u']; $conn_pass = $options['p']; } else { $conn_user = PhabricatorEnv::getEnvConfig('mysql.user'); $conn_pass = PhabricatorEnv::getEnvConfig('mysql.pass'); } $conn_host = PhabricatorEnv::getEnvConfig('mysql.host'); $conn = new AphrontMySQLDatabaseConnection( array( 'user' => $conn_user, 'pass' => $conn_pass, 'host' => $conn_host, 'database' => null, )); try { $create_sql = <<withSuffix('sql'); $results = $finder->find(); $patches = array(); foreach ($results as $r) { $matches = array(); if (preg_match('/(\d+)\..*\.sql$/', $r, $matches)) { $patches[] = array('version' => (int)$matches[1], 'file' => $r); } else { print "*** WARNING : File {$r} does not follow the normal naming ". "convention. ***\n"; } } // Files are in some 'random' order returned by the operating system // We need to apply them in proper order $patches = isort($patches, 'version'); $patch_applied = false; foreach ($patches as $patch) { if ($patch['version'] < $next_version) { continue; } print "Applying patch {$patch['file']}\n"; $path = Filesystem::resolvePath($patches_dir.$patch['file']); list($stdout, $stderr) = execx( "mysql --user=%s --password=%s --host=%s < %s", $conn_user, $conn_pass, $conn_host, $path); if ($stderr) { print $stderr; exit(-1); } // Patch was successful, update the db with the latest applied patch version // 'DELETE' and 'INSERT' instead of update, because the table might be empty queryfx( $conn, 'DELETE FROM phabricator_meta_data.%T', SCHEMA_VERSION_TABLE_NAME); queryfx( $conn, 'INSERT INTO phabricator_meta_data.%T VALUES (%d)', SCHEMA_VERSION_TABLE_NAME, $patch['version']); $patch_applied = true; } if (!$patch_applied) { print "Your database is already up-to-date.\n"; } } catch (AphrontQueryAccessDeniedException $ex) { echo "ACCESS DENIED\n". "The user '{$conn_user}' does not have sufficient MySQL privileges to\n". "execute the schema upgrade. Use the -u and -p flags to run as a user\n". "with more privileges (e.g., root).". "\n\n". "EXCEPTION:\n". $ex->getMessage(). "\n\n"; exit(1); } function usage() { echo "usage: upgrade_schema.php [-v version] [-u user -p pass]". "\n\n". "Run 'upgrade_schema.php -v 12' to apply all patches starting from ". "version 12.\n". "Run 'upgrade_schema.php -u root -p hunter2' to override the configured ". "default user.\n"; exit(1); }