sync.sql.inc

  1. 6.x commands/sql/sync.sql.inc
  2. 3.x commands/sql/sync.sql.inc
  3. 4.x commands/sql/sync.sql.inc
  4. 5.x commands/sql/sync.sql.inc

Functions

Namesort ascending Description
sql_drush_sql_sync_sanitize Sql sync sanitization function. This hook function will sanitize usernames, passwords, and sessions when the --sanitize option is used. It is also an example of how to write a database sanitizer for sql sync.
drush_sql_sync_init Sql sync init function. Bootstrap either the source or the destination site. At least one of the sites must be local for this to work; if both sites are remote, then it clearly will not be possible to bootstrap to either of them. If both are local,…
drush_sql_sync
drush_sql_post_sql_sync Apply all post-sync operations that were registered in any pre-sync hook. Follow the pattern of this function to make your own post-sync hook. If changing the database, be sure to also include a pre-sync hook to notify the user of the change that will…

File

commands/sql/sync.sql.inc
View source
  1. <?php
  2. require_once DRUSH_BASE_PATH . '/commands/core/rsync.core.inc';
  3. /**
  4. * Sql sync init function. Bootstrap either the source or the
  5. * destination site. At least one of the sites
  6. * must be local for this to work; if both sites are remote,
  7. * then it clearly will not be possible to bootstrap to
  8. * either of them. If both are local, the source site is preferred.
  9. */
  10. function drush_sql_sync_init($source = NULL, $destination = NULL) {
  11. // Preflight destination in case it defines the alias used by the source
  12. _drush_sitealias_get_record($destination);
  13. // After preflight, get source and destination settings
  14. $source_settings = drush_sitealias_get_record($source);
  15. $destination_settings = drush_sitealias_get_record($destination);
  16. // Apply command-specific options.
  17. drush_sitealias_command_default_options($source_settings, 'source-');
  18. drush_sitealias_command_default_options($destination_settings, 'target-');
  19. // Insure that we have database records for the source and destination
  20. // alias records. sitealias_get_databases_from_record will cache the
  21. // database info inside the alias records, and drush_sitealias_set_alias_context
  22. // will copy the database record into the 'alias' context. We do not
  23. // actually use the databases record at this time.
  24. sitealias_get_databases_from_record($source_settings);
  25. sitealias_get_databases_from_record($destination_settings);
  26. // Bootstrap to the source sites being sync'ed if it is local.
  27. // This allows modules enabled in the site to participate in the
  28. // sql-sync hook functions (e.g. to add sanitization operations, etc.).
  29. // If the source is remote and the destination is local, then we
  30. // will determine the sanitization operations after the database
  31. // has been copied.
  32. if (!drush_get_option('deferred-sanitization', FALSE) && drush_get_option(array('sanitize', 'destination-sanitize'), FALSE)) {
  33. $bootstrapped = drush_bootstrap_max_to_sitealias($source_settings);
  34. if ($bootstrapped) {
  35. drush_command_invoke_all('drush_sql_sync_sanitize', $source);
  36. }
  37. else {
  38. drush_set_option('deferred-sanitization', TRUE);
  39. }
  40. }
  41. // By default, sql-sync will do an ordered dump.
  42. // Set --no-ordered-dump to override.
  43. if (!drush_get_option('no-ordered-dump', FALSE)) {
  44. drush_set_option('ordered-dump', TRUE);
  45. }
  46. return TRUE;
  47. }
  48. /**
  49. * Sql sync sanitization function. This hook function will sanitize usernames,
  50. * passwords, and sessions when the --sanitize option is used. It is
  51. * also an example of how to write a database sanitizer for sql sync.
  52. *
  53. * To write your own sync hook function, define mymodule_drush_sql_sync_sanitize()
  54. * and follow the form of this function to add your own database
  55. * sanitization operations via the register post-sync op function;
  56. * @see drush_sql_register_post_sync_op(). This is the only thing that the
  57. * sync hook function needs to do; sql-sync takes care of the rest.
  58. *
  59. * The function below has a lot of logic to process user preferences and
  60. * generate the correct SQL regardless of whether Postgres, Mysql,
  61. * Drupal 6 or Drupal 7 is in use. A simpler sanitize function that
  62. * always used default values and only worked with Drupal 6 + mysql
  63. * appears in the drush.api.php. @see hook_drush_sql_sync_sanitize().
  64. */
  65. function sql_drush_sql_sync_sanitize($site) {
  66. $site_settings = drush_sitealias_get_record($site);
  67. $databases = sitealias_get_databases_from_record($site_settings);
  68. $prefix = $databases['default']['default']['prefix'];
  69. $prefix = isset($databases['default']['default']['prefix']) ? $databases['default']['default']['prefix'] : '';
  70. $user_table_updates = array();
  71. $message_list = array();
  72. // Sanitize passwords.
  73. $newpassword = drush_get_option(array('sanitize-password', 'destination-sanitize-password'), 'password');
  74. if ($newpassword != 'no' && $newpassword !== 0) {
  75. $major_version = drush_drupal_major_version();
  76. $pw_op = "";
  77. // In Drupal 6, passwords are hashed via the MD5 algorithm.
  78. if ($major_version == 6) {
  79. $pw_op = "MD5('$newpassword')";
  80. }
  81. // In Drupal 7, passwords are hashed via a more complex algorithm,
  82. // available via the user_hash_password function.
  83. elseif ($major_version >= 7) {
  84. $core = DRUSH_DRUPAL_CORE;
  85. include_once $core . '/includes/password.inc';
  86. include_once $core . '/includes/bootstrap.inc';
  87. $hash = user_hash_password($newpassword);
  88. $pw_op = "'$hash'";
  89. }
  90. if (!empty($pw_op)) {
  91. $user_table_updates[] = "pass = $pw_op";
  92. $message_list[] = "passwords";
  93. }
  94. }
  95. // Sanitize email addresses.
  96. $newemail = drush_get_option(array('sanitize-email', 'destination-sanitize-email'), 'user+%uid@localhost.localdomain');
  97. if ($newemail != 'no' && $newemail !== 0) {
  98. if (strpos($newemail, '%') !== FALSE) {
  99. // We need a different sanitization query for Postgres and Mysql.
  100. $db_driver = $databases['default']['default']['driver'];
  101. if ($db_driver == 'pgsql') {
  102. $email_map = array('%uid' => "' || uid || '", '%mail' => "' || replace(mail, '@', '_') || '", '%name' => "' || replace(name, ' ', '_') || '");
  103. $newmail = "'" . str_replace(array_keys($email_map), array_values($email_map), $newemail) . "'";
  104. }
  105. else {
  106. $email_map = array('%uid' => "', uid, '", '%mail' => "', replace(mail, '@', '_'), '", '%name' => "', replace(name, ' ', '_'), '");
  107. $newmail = "concat('" . str_replace(array_keys($email_map), array_values($email_map), $newemail) . "')";
  108. }
  109. $user_table_updates[] = "mail = $newmail, init = $newmail";
  110. }
  111. else {
  112. $user_table_updates[] = "mail = '$newemail', init = '$newmail'";
  113. }
  114. $message_list[] = 'email addresses';
  115. }
  116. if (!empty($user_table_updates)) {
  117. $sanitize_query = "UPDATE {$prefix}users SET " . implode(', ', $user_table_updates) . " WHERE uid > 0;";
  118. drush_sql_register_post_sync_op('user-email', dt('Reset !message in user table', array('!message' => implode(' and ', $message_list))), $sanitize_query);
  119. }
  120. // Seems quite portable (SQLite?) - http://en.wikipedia.org/wiki/Truncate_(SQL)
  121. $sql_sessions = "TRUNCATE TABLE {$prefix}sessions;";
  122. drush_sql_register_post_sync_op('sessions', dt('Truncate Drupal\'s sessions table'), $sql_sessions);
  123. }
  124. function drush_sql_sync($source = NULL, $destination = NULL) {
  125. $source_settings = drush_sitealias_overlay_options(drush_sitealias_get_record($source), 'source-');
  126. $destination_settings = drush_sitealias_overlay_options(drush_sitealias_get_record($destination), 'target-');
  127. $source_os = drush_os($source_settings);
  128. $target_os = drush_os($destination_settings);
  129. // Check to see if this is an sql-sync multiple command (multiple sources and multiple destinations)
  130. $is_multiple = drush_do_multiple_command('sql-sync', $source_settings, $destination_settings);
  131. if ($is_multiple === FALSE) {
  132. // Get the options for the source and target databases
  133. $source_db_url = drush_sitealias_get_db_spec($source_settings, FALSE, 'source-');
  134. // The host may have special ssh requirements
  135. $source_remote_ssh_options = drush_sitealias_get_option($source_settings, 'ssh-options');
  136. // rsync later will also have to know this option
  137. $source_rsync_options = array('ssh-options' => $source_remote_ssh_options);
  138. $target_db_url = drush_sitealias_get_db_spec($destination_settings, FALSE, 'target-');
  139. // The host may have special ssh requirements
  140. $target_remote_ssh_options = drush_sitealias_get_option($destination_settings, 'ssh-options');
  141. // rsync later will also have to know this option
  142. $target_rsync_options = array('ssh-options' => $target_remote_ssh_options);
  143. if (empty($source_db_url)) {
  144. if (empty($source_settings)) {
  145. return drush_set_error('DRUSH_ALIAS_NOT_FOUND', dt('Error: no alias record could be found for source !source', array('!source' => $source)));
  146. }
  147. return drush_set_error('DRUSH_DATABASE_NOT_FOUND', dt('Error: no database record could be found for source !source', array('!source' => $source)));
  148. }
  149. if (empty($target_db_url)) {
  150. if (empty($destination_settings)) {
  151. return drush_set_error('DRUSH_ALIAS_NOT_FOUND', dt('Error: no alias record could be found for target !destination', array('!destination' => $destination)));
  152. }
  153. return drush_set_error('DRUSH_DATABASE_NOT_FOUND', dt('Error: no database record could be found for target !destination', array('!destination' => $destination)));
  154. }
  155. if (isset($source_db_url['remote-host']) && isset($target_db_url['remote-host']) && ($source_db_url['remote-host'] == $target_db_url['remote-host']) && ($source_db_url['database'] == $target_db_url['database']) && !drush_get_context('DRUSH_SIMULATE')) {
  156. return drush_set_error('DRUSH_SAME_DATABASE', dt('Source and target databases are the same; please sync to a different target.'));
  157. }
  158. // Set up the result file and the remote file.
  159. // If the result file is not set, then create a temporary file.
  160. // If the remote file is not set, use the same name for the remote
  161. // and local files and hope for the best.
  162. $source_dump = drush_sql_dump_file($source_settings);
  163. $target_dump = drush_sql_dump_file($destination_settings);
  164. $use_temp_files = drush_get_option('temp');
  165. // Only use one dump file if both the source and the target are on the local machine
  166. if (!isset($source_db_url['remote-host']) && !isset($target_db_url['remote-host'])) {
  167. if ((!$destination_settings['dump-is-temp']) && ($source_settings['dump-is-temp'])) {
  168. $source_dump = $target_dump;
  169. $source_settings['dump-is-temp'] = FALSE;
  170. }
  171. else {
  172. $target_dump = $source_dump;
  173. $destination_settings['dump-is-temp'] = $source_settings['dump-is-temp'];
  174. }
  175. $local_file = $source_dump;
  176. }
  177. else {
  178. // If one of the systems is remote, then set the --remove-source-files
  179. // rsync option if the source dump file is temporary. This will get
  180. // rsync to clean up after us automatically; useful if the source is remote.
  181. if ($source_settings['dump-is-temp']) {
  182. $source_rsync_options['remove-source-files'] = TRUE;
  183. }
  184. // Set $local_file to whichever side of the operation is local, or make
  185. // a temporary file if both source and target are remote.
  186. if (!isset($source_db_url['remote-host'])) {
  187. $local_file = $source_dump;
  188. }
  189. elseif (!isset($target_db_url['remote-host'])) {
  190. $local_file = $target_dump;
  191. }
  192. else {
  193. $local_file = drush_tempnam($source_db_url['database'] . ($source_db_url['database'] == $target_db_url['database'] ? '' : '-to-' . $target_db_url['database']) . '.sql.');
  194. }
  195. }
  196. // If source is remote, then use ssh to dump the database and then rsync to local machine
  197. // If source is local, call drush_sql_dump to dump the database to local machine
  198. // In either case, the '--no-dump' option will cause the sql-dump step to be skipped, and
  199. // we will import from the existing local file (first using rsync to fetch it if it does not exist)
  200. //
  201. // No dump affects both local and remote sql-dumps; it prevents drush sql-sync
  202. // from calling sql-dump when the local cache file is newer than the cache threshhold
  203. // No sync affects the remote sql-dump; it will prevent drush sql-sync from
  204. // rsyncing the local sql-dump file with the remote sql-dump file.
  205. $no_sync = drush_sitealias_get_option($source_settings, 'no-sync');
  206. $no_dump = drush_sitealias_get_option($source_settings, 'no-dump');
  207. $no_cache = drush_sitealias_get_option($source_settings, 'no-cache');
  208. if (!isset($no_cache)) {
  209. $cache = drush_sitealias_get_option($source_settings, 'cache');
  210. if (!isset($cache)) {
  211. $cache = 24; // Default cache is 24 hours if nothing else is specified.
  212. }
  213. }
  214. // If the 'cache' option is set, then we will set the no-dump option iff the
  215. // target file exists and its modification date is less than "cache" hours.
  216. // If --no-sync or --no-dump are already set, then this check is unnecessary.
  217. if (isset($cache) && !isset($no_sync) && !isset($no_dump)) {
  218. if (file_exists($local_file) && (filesize($local_file) > 0)) {
  219. if ((time() - filemtime($local_file)) < ($cache * 60 * 60)) {
  220. drush_log(dt('Modification time of local dump file !file is less than !cache hours old. Use the --no-cache option to force a refresh.', array('!file' => $local_file, '!cache' => $cache)), 'warning');
  221. $no_dump = TRUE;
  222. $no_sync = TRUE;
  223. }
  224. else {
  225. drush_log(dt('Local sql cache file exists but is greater than !cache hours old.', array('!cache' => $cache)));
  226. }
  227. }
  228. else {
  229. drush_log('Local sql cache file does not exist.');
  230. }
  231. }
  232. $table_selection = array();
  233. if (!isset($no_dump)) {
  234. $table_selection = drush_sql_get_expanded_table_selection($source_db_url, $source);
  235. }
  236. // Prompt for confirmation. This is destructive.
  237. if (!drush_get_context('DRUSH_SIMULATE')) {
  238. // Check to see if we are using a temporary file in a situation
  239. // where the user did not specify "--temp".
  240. if (($source_settings['dump-is-temp'] || $destination_settings['dump-is-temp']) && (!isset($use_temp_files)) && (isset($source_db_url['remote-host']) || isset($target_db_url['remote-host']))) {
  241. drush_print(dt('WARNING: Using temporary files to store and transfer sql-dump. It is recommended that you specify --source-dump and --target-dump options on the command line, or set \'%dump\' or \'%dump-dir\' in the path-aliases section of your site alias records. This facilitates fast file transfer via rsync.'));
  242. }
  243. if (array_key_exists('tables', $table_selection) && (count($table_selection['tables']) > 0)) {
  244. drush_print();
  245. drush_print(dt(' Only the following tables will be transferred: !list', array('!list' => implode(',', $table_selection['tables']))));
  246. }
  247. elseif (!empty($table_selection)) {
  248. $skip_tables_list = implode(',', $table_selection['skip'] + $table_selection['structure']);
  249. if(!empty($skip_tables_list)) {
  250. drush_print();
  251. drush_print(dt(' The following tables will be skipped: !list', array('!list' => $skip_tables_list)));
  252. }
  253. }
  254. // If there are multiple destinations, then
  255. // prompt once here and suppress the warning message
  256. // and the normal confirmation below.
  257. if (array_key_exists('site-list', $destination_settings)) {
  258. drush_print();
  259. drush_print(dt('You are about to sync the database from !source, overwriting all of the following targets:', array('!source' => $source)));
  260. foreach ($destination_settings['site-list'] as $one_destination) {
  261. drush_print(dt(' !target', array('!target' => $one_destination)));
  262. }
  263. }
  264. else {
  265. drush_print();
  266. $txt_source = (isset($source_db_url['remote-host']) ? $source_db_url['remote-host'] . '/' : '') . $source_db_url['database'];
  267. $txt_destination = (isset($target_db_url['remote-host']) ? $target_db_url['remote-host'] . '/' : '') . $target_db_url['database'];
  268. drush_print(dt("You will destroy data in !target and replace with data from !source.", array('!source' => $txt_source, '!target' => $txt_destination)));
  269. }
  270. // If any sanitization operations are to be done, then get the
  271. // sanitization messages and print them as part of the confirmation.
  272. // If --sanitize was specified but there were no sanitize messages,
  273. // then warn that sanitization operations will be accumulated and
  274. // processed after the sync completes.
  275. $messages = _drush_sql_get_post_sync_messages();
  276. if ($messages) {
  277. drush_print();
  278. drush_print($messages);
  279. }
  280. else if (drush_get_option('deferred-sanitization', FALSE) && !drush_get_option('confirm-sanitizations', FALSE)) {
  281. drush_print();
  282. drush_print("WARNING: --sanitize was specified, but deferred (e.g. the source site is remote). The sanitization operations will be determined after the database is copied to the local system and will be run without further confirmation. Run with --confirm-sanitizations to force confirmation after the sync.");
  283. }
  284. // TODO: actually make the backup if desired.
  285. drush_print();
  286. drush_print(dt("You might want to make a backup first, using the sql-dump command.\n"));
  287. if (!drush_confirm(dt('Do you really want to continue?'))) {
  288. return drush_user_abort();
  289. }
  290. }
  291. if (!isset($no_dump)) {
  292. if (isset($source_db_url['remote-host'])) {
  293. $source_remote_user = '';
  294. $source_at = '';
  295. if (array_key_exists('remote-user', $source_settings)) {
  296. $source_remote_user = $source_settings['remote-user'];
  297. $source_at ='@';
  298. $source_remote_pass = array_key_exists('remote-pass', $source_settings) ? ':' . $source_settings['remote-pass'] : '';
  299. }
  300. $source_intermediate = $source_dump;
  301. $mv_intermediate = '';
  302. // If we are doing a remote dump and the source is not a temporary file,
  303. // then first dump to a temporary file and move it to the specified file after
  304. // the dump is complete. This will reduce contention during simultaneous dumps
  305. // from different users sharing the same dump file.
  306. if (!drush_is_windows($source_os) && (!$source_settings['dump-is-temp'])) {
  307. $source_intermediate = $source_dump . '-' . date("U");
  308. $mv_intermediate = '&& mv -f ' . $source_intermediate . ' ' . $source_dump;
  309. }
  310. list($dump_exec, $dump_file) = drush_sql_build_dump_command($table_selection, $source_db_url, $source_intermediate);
  311. $dump_exec .= $mv_intermediate;
  312. if (!drush_is_windows($source_os) && isset($cache) && !$source_settings['dump-is-temp']) {
  313. // Inject some bash commands to remotely test the modification date of the target file
  314. // if the cache option is set.
  315. $dump_exec = 'if [ ! -s ' . $source_dump . ' ] || [ $((`date "+%s"`-`stat --format="%Y" ' . $source_dump . '`)) -gt ' . ($cache * 60 * 60) . ' ] ; then ' . $dump_exec . '; fi';
  316. }
  317. }
  318. else {
  319. list($dump_exec, $dump_file) = drush_sql_build_dump_command($table_selection, $source_db_url, $local_file);
  320. $no_sync = TRUE;
  321. }
  322. // Wrap the dump command in a remote call if the source site is remote.
  323. $dump_exec = _drush_backend_generate_command($source_settings, $dump_exec);
  324. }
  325. // Call sql-dump, either on the local machine or remotely via ssh, as appropriate.
  326. if (!empty($dump_exec)) {
  327. if (drush_op_system($dump_exec)) {
  328. return drush_set_error('DRUSH_SQL_DUMP_FAIL', 'Database dump failed');
  329. }
  330. }
  331. // If the sql-dump was remote, then rsync the file over to the local machine.
  332. if (!isset($no_sync)) {
  333. // If the source file is a temporary file, then we will have rsync
  334. // delete it for us (remove-source-files option set above).
  335. if (!drush_core_call_rsync($source_remote_user . $source_at . $source_db_url['remote-host'] . ':' . $source_dump, drush_correct_absolute_path_for_exec($local_file, "RSYNC"), $source_rsync_options)) {
  336. return FALSE;
  337. }
  338. }
  339. // We will handle lists of destination sites differently from
  340. // single source-to-destination syncs.
  341. if (array_key_exists('site-list', $destination_settings)) {
  342. // Insure that we will not dump the source sql database
  343. // repeatedly, but will instead re-use it each time through
  344. // the redispatch loop.
  345. drush_set_option('no-dump', TRUE);
  346. drush_set_option('no-sync', TRUE);
  347. drush_set_option('source-dump', $source_dump);
  348. // Call sql-sync for each destination to push the $source_dump
  349. // to each target in turn.
  350. foreach ($destination_settings['site-list'] as $one_destination) {
  351. drush_do_command_redispatch('sql-sync', array($source, $one_destination));
  352. }
  353. }
  354. else {
  355. // Prior to database import, we will generate a "create database" command
  356. // if the '--create-db' option was specified. Note that typically the
  357. // web server user will not have permissions to create a database; to specify
  358. // a different user to use with the create db command, the '--db-su' option
  359. // may be used.
  360. // Under postgres, "alter role username with createdb;" will give create database
  361. // permissions to the specified user if said user was not created with this right.
  362. $pre_import_commands = '';
  363. $create_db = drush_sitealias_get_option($destination_settings, 'create-db');
  364. if (isset($create_db)) {
  365. $create_db_su = drush_sql_su($target_db_url, $destination_settings);
  366. $db_su_connect = _drush_sql_connect($create_db_su);
  367. $pre_import_sql = drush_sql_build_createdb_sql($target_db_url);
  368. $pre_import_commands = sprintf('echo "%s" | %s; ', $pre_import_sql, $db_su_connect);
  369. // Linux requires quotes around echo statements. Windows generally supports
  370. // quotes for echo statements, but will complain if they are present
  371. // when piping echo statements as input to other commands. Also,
  372. // Windows multi-commands normally work when separated by '&&', '&', or ';'
  373. // but will not function with ';' in this case.(http://drupal.org/node/1957020)
  374. if (drush_is_windows($target_os)) {
  375. $pre_import_commands = sprintf('echo %s | %s && ', $pre_import_sql, $db_su_connect);
  376. }
  377. else {
  378. $pre_import_commands = sprintf('echo "%s" | %s; ', $pre_import_sql, $db_su_connect);
  379. }
  380. }
  381. // Generate the import command
  382. $import_command = _drush_sql_connect($target_db_url);
  383. switch (_drush_sql_get_scheme($target_db_url)) {
  384. case 'mysql':
  385. $import_command .= ' --silent';
  386. break;
  387. case 'pgsql':
  388. $import_command .= ' -q';
  389. break;
  390. }
  391. // If destination is remote, then use rsync to push the database, then use ssh to import the database
  392. // If destination is local, then just import the database locally
  393. if (isset($target_db_url['remote-host'])) {
  394. $target_remote_user = '';
  395. $target_at = '';
  396. if (array_key_exists('remote-user', $destination_settings)) {
  397. $target_remote_user = $destination_settings['remote-user'];
  398. $target_at ='@';
  399. $target_remote_pass = array_key_exists('remote-pass', $destination_settings) ? ':' . $destination_settings['remote-pass'] : '';
  400. }
  401. if (!drush_core_call_rsync(drush_correct_absolute_path_for_exec($local_file, "RSYNC"), $target_remote_user . $target_at . $target_db_url['remote-host'] . ':' . $target_dump, $target_rsync_options)) {
  402. return FALSE;
  403. }
  404. $import_exec = $pre_import_commands . $import_command . ' < ' . drush_escapeshellarg($target_dump, $target_os);
  405. // Delete the remote target file if it is a temporary file.
  406. if (!drush_is_windows($target_os) && $destination_settings['dump-is-temp']) {
  407. $import_exec .= '; rm -f ' . drush_escapeshellarg($target_dump, $target_os);
  408. }
  409. // TODO: make sure that the remote tmp file is deleted on remote Windows machines.
  410. }
  411. else {
  412. $import_exec = $pre_import_commands . $import_command . ' < ' . drush_escapeshellarg($local_file);
  413. }
  414. $import_exec = _drush_backend_generate_command($destination_settings, $import_exec);
  415. drush_op_system($import_exec);
  416. // After the database is imported into the destination, we
  417. // will check and see if we did not collect sanitization
  418. // operations in drush_sql_sync_init (i.e. because the source
  419. // site was remote), and if the destination site is local,
  420. // then we will call the sanitization hooks now.
  421. // This presumes an important precondition, that the code
  422. // files were sync'ed before the database was sync'ed.
  423. if (drush_get_option('deferred-sanitization', FALSE) && (drush_has_boostrapped(DRUSH_BOOTSTRAP_DRUPAL_SITE) == FALSE)) {
  424. $bootstrapped = drush_bootstrap_max_to_sitealias($destination_settings);
  425. if ($bootstrapped) {
  426. drush_command_invoke_all('drush_sql_sync_sanitize', $destination);
  427. }
  428. }
  429. }
  430. }
  431. }
  432. /**
  433. * Apply all post-sync operations that were registered in any pre-sync hook.
  434. * Follow the pattern of this function to make your own post-sync hook.
  435. * If changing the database, be sure to also include a pre-sync hook to
  436. * notify the user of the change that will be made. @see drush_sql_pre_sql_sync().
  437. */
  438. function drush_sql_post_sql_sync($source = NULL, $destination = NULL) {
  439. $options = drush_get_context('post-sync-ops');
  440. if (!empty($options)) {
  441. // If 'deferred-sanitization' is set, then we collected the
  442. // sanitization operations -after- the database sync, which
  443. // means they were not confirmed up-front. We will show the
  444. // operations here, but we will not offer an opportunity to
  445. // confirm unless --confirm-sanitizations is specified.
  446. if (drush_get_option('deferred-sanitization', FALSE) || drush_get_option('confirm-sanitizations', FALSE)) {
  447. if (!drush_get_context('DRUSH_SIMULATE')) {
  448. $messages = _drush_sql_get_post_sync_messages();
  449. if ($messages) {
  450. drush_print();
  451. drush_print($messages);
  452. if (drush_get_option('confirm-sanitizations', FALSE)) {
  453. if (!drush_confirm(dt('Do you really want to sanitize?'))) {
  454. // Do not abort or return FALSE; that would trigger a rollback.
  455. // Just skip the sanitizations and signal that all is ok.
  456. drush_log(dt('Sanitizations skipped.'), 'ok');
  457. return TRUE;
  458. }
  459. }
  460. }
  461. }
  462. }
  463. $destination_settings = drush_sitealias_get_record($destination);
  464. $sanitize_query = '';
  465. foreach($options as $id => $data) {
  466. $sanitize_query .= $data['query'] . " ";
  467. }
  468. if ($sanitize_query) {
  469. if (!drush_get_context('DRUSH_SIMULATE')) {
  470. $result = drush_invoke_process($destination_settings, "sql-query", array($sanitize_query));
  471. }
  472. else {
  473. drush_print("Executing on $destination: $sanitize_query");
  474. }
  475. }
  476. }
  477. }