Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
hipo_job_rollback_management.inc
1 <?php
17 require_once SQ_SYSTEM_ROOT.'/core/hipo/hipo_job.inc';
18 require_once SQ_INCLUDE_PATH.'/rollback_management.inc';
19 
39 {
40 
41 
47  function HIPO_Job_Rollback_Management($code_name='')
48  {
49  // We'll do our own transactions thanks
50  $this->uses_trans = FALSE;
51 
52  $this->HIPO_Job($code_name);
53 
54  }//end constructor
55 
56 
66  public static function paintConfig(&$o, $class, $write_access)
67  {
68 
69  }//end paintConfig()
70 
71 
78  public static function getConfigVars()
79  {
80  return Array(
81  'SQ_HIPO_ROLLBACK_MANAGEMENT_THRESHOLD' => Array('editable' => 1, 'default' => 1),
82  );
83 
84  }//end getConfigVars()
85 
86 
93  function getHipoName()
94  {
95  return translate('hipo_name_rollback_management');
96 
97  }//end getHipoName()
98 
99 
108  {
109  return Array(
110  Array(
111  'name' => translate('hipo_job_rollback_changing_rb_config'),
112  'function_call' => Array(
113  'process_function' => 'changeRollbackSetting',
114  ),
115  'running_mode' => 'server',
116  'auto_step' => TRUE,
117  'allow_cancel' => FALSE,
118  'percent_done' => 0,
119  'complete' => FALSE,
120  'message' => '',
121  ),
122  Array(
123  'name' => translate('hipo_job_rollback_configuring_db_triggers'),
124  'function_call' => Array(
125  'process_function' => 'configureDBTriggers',
126  ),
127  'running_mode' => 'server',
128  'auto_step' => TRUE,
129  'allow_cancel' => FALSE,
130  'percent_done' => 0,
131  'complete' => FALSE,
132  'message' => '',
133  ),
134  Array(
135  'name' => translate('hipo_job_rollback_opening_db_transaction'),
136  'function_call' => Array(
137  'process_function' => 'openTransaction',
138  ),
139  'running_mode' => 'server',
140  'auto_step' => TRUE,
141  'allow_cancel' => FALSE,
142  'percent_done' => 0,
143  'complete' => FALSE,
144  'message' => '',
145  ),
146  Array(
147  'name' => translate('hipo_job_rollback_purging_file_versioning'),
148  'function_call' => Array(
149  'process_function' => 'purgeFileVersioning',
150  ),
151  'running_mode' => 'server',
152  'auto_step' => TRUE,
153  'allow_cancel' => TRUE,
154  'percent_done' => 0,
155  'complete' => FALSE,
156  'message' => '' ,
157  ),
158  Array(
159  'name' => translate('hipo_job_rollback_resetting_rollback'),
160  'function_call' => Array(
161  'process_function' => 'resetRollback',
162  ),
163  'running_mode' => 'server',
164  'auto_step' => TRUE,
165  'allow_cancel' => TRUE,
166  'percent_done' => 0,
167  'complete' => FALSE,
168  'message' => '',
169  ),
170  Array(
171  'name' => translate('hipo_job_rollback_toggling_rb_state'),
172  'function_call' => Array(
173  'process_function' => 'toggleRollbackState',
174  ),
175  'running_mode' => 'server',
176  'auto_step' => TRUE,
177  'allow_cancel' => TRUE,
178  'percent_done' => 0,
179  'complete' => FALSE,
180  'message' => '',
181  ),
182  Array(
183  'name' => translate('hipo_job_rollback_deleting_rb_entries'),
184  'function_call' => Array(
185  'process_function' => 'deleteRollbackEntries',
186  ),
187  'running_mode' => 'server',
188  'auto_step' => TRUE,
189  'allow_cancel' => TRUE,
190  'percent_done' => 0,
191  'complete' => FALSE,
192  'message' => '',
193  ),
194  Array(
195  'name' => translate('hipo_job_rollback_aligning_rb_entries'),
196  'function_call' => Array(
197  'process_function' => 'alignRollbackEntries',
198  ),
199  'running_mode' => 'server',
200  'auto_step' => TRUE,
201  'allow_cancel' => TRUE,
202  'percent_done' => 0,
203  'complete' => FALSE,
204  'message' => '',
205  ),
206  Array(
207  'name' => translate('hipo_job_rollback_delete_redundant_rb_entries'),
208  'function_call' => Array(
209  'process_function' => 'deleteRedundantRollbackEntries',
210  ),
211  'running_mode' => 'server',
212  'auto_step' => TRUE,
213  'allow_cancel' => TRUE,
214  'percent_done' => 0,
215  'complete' => FALSE,
216  'message' => '',
217  ),
218  Array(
219  'name' => translate('hipo_job_rollback_completing_db_transaction'),
220  'function_call' => Array(
221  'process_function' => 'completeTransaction',
222  ),
223  'running_mode' => 'server',
224  'auto_step' => TRUE,
225  'allow_cancel' => FALSE,
226  'percent_done' => 0,
227  'complete' => FALSE,
228  'message' => '',
229  ),
230  );
231 
232  }//end getInitialStepData()
233 
234 
245  {
246  return 100;
247 
248  }//end getThresholdPercentageRequired()
249 
250 
257  function prepare()
258  {
259  require SQ_DATA_PATH.'/private/db/table_columns.inc';
260 
261  $this->_running_vars['rollback_table_columns'] = $tables;
262  $this->_running_vars['rollback_table_names'] = get_rollback_table_names();
263  $this->_running_vars['start_job'] = TRUE;
264 
265  return parent::prepare();
266 
267  }//end prepare()
268 
269 
276  function freestyle()
277  {
278  if (!$this->changeRollbackSetting($this->_steps[0], $this->getCodeName())) {
279  return FALSE;
280  }
281 
282  if (!$this->configureDBTriggers($this->_steps[1], $this->getCodeName())) {
283  return FALSE;
284  }
285 
286  if (!$this->openTransaction($this->_steps[2], $this->getCodeName())) {
287  return FALSE;
288  }
289 
290  if (!$this->purgeFileVersioning($this->_steps[3], $this->getCodeName())) {
291  return FALSE;
292  }
293 
294  if (!$this->resetRollback($this->_steps[4], $this->getCodeName())) {
295  return FALSE;
296  }
297 
298  if (!$this->toggleRollbackState($this->_steps[5], $this->getCodeName())) {
299  return FALSE;
300  }
301 
302  if (!$this->deleteRollbackEntries($this->_steps[6], $this->getCodeName())) {
303  return FALSE;
304  }
305 
306  if (!$this->alignRollbackEntries($this->_steps[7], $this->getCodeName())) {
307  return FALSE;
308  }
309 
310  if (!$this->deleteRedundantRollbackEntries($this->_steps[8], $this->getCodeName())) {
311  return FALSE;
312  }
313 
314  if (!$this->completeTransaction($this->_steps[9], $this->getCodeName())) {
315  return FALSE;
316  }
317 
318  return TRUE;
319 
320  }//end freestyle()
321 
322 
332  function changeRollbackSetting(&$step_data, $prefix)
333  {
334  $saved = TRUE;
335 
336  // Set SQ_CONF_ROLLBACK_ENABLED in the System Config if we are about to change state
337  if (($this->_running_vars['enable_rollback']) || ($this->_running_vars['disable_rollback'])) {
338  $saved = FALSE;
339 
340  include_once(SQ_INCLUDE_PATH.'/system_config.inc');
341  $system_conf = new System_Config();
342  if (!$system_conf->canAcquireLock()) {
343  trigger_localised_error('CORE0233', E_USER_NOTICE);
344  // Fail
345  return FALSE;
346  }
347 
348  $enable_rollback = (($this->_running_vars['enable_rollback']) ? '1' : '0');
349 
350  $system_conf->acquireLock();
351  $saved = $system_conf->save(Array('SQ_CONF_ROLLBACK_ENABLED' => $enable_rollback), FALSE, FALSE);
352  $system_conf->releaseLock();
353  } else {
354  $this->skipStep(2);
355  }
356 
357  $step_data['percent_done'] = 100;
358  $step_data['complete'] = TRUE;
359 
360  return $saved;
361 
362  }//end changeRollbackSetting()
363 
364 
375  function configureDBTriggers(&$step_data, $prefix)
376  {
377  $success = TRUE;
378 
379  if (($this->_running_vars['enable_rollback']) || ($this->_running_vars['disable_rollback'])) {
380  $success = FALSE;
381 
382  ob_start();
383 
384  require_once SQ_SYSTEM_ROOT.'/install/install.inc';
385  require_once SQ_LIB_PATH.'/db_install/db_install.inc';
386  require_once SQ_INCLUDE_PATH.'/system_config.inc';
387  require_once SQ_LIB_PATH.'/file_versioning/file_versioning.inc';
388  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
389 
390  $GLOBALS['SQ_SYSTEM']->setRunLevel(SQ_RUN_LEVEL_FORCED);
391 
392  $cached_table_columns = Array();
393 
394  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
395  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
396 
397  install_stored_relations('functions');
398 
399  if (file_exists(SQ_DATA_PATH.'/private/db/table_columns.inc')) {
400  unlink(SQ_DATA_PATH.'/private/db/table_columns.inc');
401  }
402 
403  if (!db_install(SQ_CORE_PACKAGE_PATH.'/tables.xml')) {
404  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
405  trigger_error('TABLE INSTALL FAILURE', E_USER_ERROR);
406  }
407 
408  // install any tables needed by the packages
409  $packages = get_package_list();
410 
411  foreach ($packages as $package) {
412  $xml_file = SQ_PACKAGES_PATH.'/'.$package.'/tables.xml';
413  if (file_exists($xml_file)) {
414  if (!db_install($xml_file)) {
415  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
416  trigger_error('TABLE INSTALL FAILURE', E_USER_ERROR);
417  }
418  install_stored_relations('functions', $package);
419  }
420  }
421 
422  install_stored_relations('views');
423 
424  // grant permissions to the tables for the secondary user
425  grant_secondary_user_perms();
426 
427  $fv = $GLOBALS['SQ_SYSTEM']->getFileVersioning();
428 
429  if (!$fv->initRepository()) {
430  trigger_error('Unable to initialise File Versioning Repository', E_USER_ERROR);
431  }
432 
433  ob_end_clean();
434 
435  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
436  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
437  $GLOBALS['SQ_SYSTEM']->restoreRunLevel();
438 
439  $success = TRUE;
440  }//end if
441 
442  $step_data['percent_done'] = 100;
443  $step_data['complete'] = TRUE;
444 
445  return $success;
446 
447  }//end configureDBTriggers()
448 
449 
459  function openTransaction(&$step_data, $prefix)
460  {
461  $step_data['percent_done'] = 100;
462  $step_data['complete'] = TRUE;
463 
464  // Start a transaction. Why not?
465  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
466  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
467 
468  return TRUE;
469 
470  }//end openTransaction()
471 
472 
482  function purgeFileVersioning(&$step_data, $prefix)
483  {
484  if (!empty($this->_running_vars['purge_fv_date'])) {
485  if ($this->_running_vars['start_job']) {
486  $this->_running_vars['start_job'] = FALSE;
487  }
488 
489  // Purge file versioning entries, 50 at a time
490  $affected_rows = purge_file_versioning($this->_running_vars['purge_fv_date'], 50);
491 
492  if ($affected_rows == 0) {
493  $step_data['percent_done'] = 100;
494  $step_data['complete'] = TRUE;
495  $this->_running_vars['start_job'] = TRUE;
496  $this->skipStep(3);
497  $this->skipStep(4);
498  $this->skipStep(5);
499  $this->skipStep(6);
500  } else {
501  $step_data['percent_done'] = 50;
502  $step_data['complete'] = FALSE;
503  }
504  } else {
505  $step_data['percent_done'] = 100;
506  $step_data['complete'] = TRUE;
507  $this->_running_vars['start_job'] = TRUE;
508  }
509 
510  return TRUE;
511 
512  }//end purgeFileVersioning()
513 
514 
524  function resetRollback(&$step_data, $prefix)
525  {
526  if ($this->_running_vars['reset_rollback']) {
527  if ($this->_running_vars['start_job']) {
528  $this->_running_vars['start_job'] = FALSE;
529  $this->_running_vars['to_check'] = $this->_running_vars['rollback_table_names'];
530  }
531 
532  if (!empty($this->_running_vars['to_check'])) {
533  reset($this->_running_vars['to_check']);
534  list($key, $table_name) = each($this->_running_vars['to_check']);
535  unset($this->_running_vars['to_check'][$key]);
536 
537  $step_data['message'] = translate('hipo_job_rollback_truncating_rb_entries_in', $table_name);
538  truncate_rollback_entries($table_name);
539  }
540 
541  if (empty($this->_running_vars['to_check'])) {
542  $step_data['percent_done'] = 100;
543  $step_data['complete'] = TRUE;
544  $this->_running_vars['start_job'] = TRUE;
545  } else {
546  $step_data['percent_done'] = (int)(((count($this->_running_vars['rollback_table_names']) - count($this->_running_vars['to_check'])) / count($this->_running_vars['rollback_table_names'])) * 100);
547  $step_data['complete'] = FALSE;
548  }
549  } else {
550  $step_data['percent_done'] = 100;
551  $step_data['complete'] = TRUE;
552  $this->_running_vars['start_job'] = TRUE;
553  }
554 
555  return TRUE;
556 
557  }//end resetRollback()
558 
559 
569  function toggleRollbackState(&$step_data, $prefix)
570  {
571  if ($this->_running_vars['start_job']) {
572  $this->_running_vars['start_job'] = FALSE;
573  $this->_running_vars['to_check'] = $this->_running_vars['rollback_table_names'];
574 
575  if ($this->_running_vars['enable_rollback']) {
576  $rbfound = rollback_found($this->_running_vars['to_check']);
577  if ($rbfound) {
578  $step_data['percent_done'] = 100;
579  $step_data['complete'] = TRUE;
580  $this->_running_vars['start_job'] = TRUE;
581  $this->skipStep(5);
582  $this->skipStep(6);
583  return TRUE;
584  }
585  }
586  }
587 
588  if ((!empty($this->_running_vars['to_check'])) && (($this->_running_vars['enable_rollback']) || ($this->_running_vars['disable_rollback']))) {
589  reset($this->_running_vars['to_check']);
590  list($key, $table_name) = each($this->_running_vars['to_check']);
591  unset($this->_running_vars['to_check'][$key]);
592 
593  if ($this->_running_vars['enable_rollback']) {
594  $step_data['message'] = translate('hipo_job_rollback_opening_rb_entries_in', $table_name);
595  open_rollback_entries($table_name, $this->_running_vars['rollback_table_columns'], $this->_running_vars['rollback_date']);
596  } else if ($this->_running_vars['disable_rollback']) {
597  $step_data['message'] = translate('hipo_job_rollback_closing_rb_entries_in', $table_name);
598  close_rollback_entries($table_name, $this->_running_vars['rollback_date']);
599  }
600 
601  if (empty($this->_running_vars['to_check'])) {
602  $step_data['percent_done'] = 100;
603  $step_data['complete'] = TRUE;
604  $this->_running_vars['start_job'] = TRUE;
605  $this->skipStep(5);
606  $this->skipStep(6);
607  } else {
608  $step_data['percent_done'] = (int)(((count($this->_running_vars['rollback_table_names']) - count($this->_running_vars['to_check'])) / count($this->_running_vars['rollback_table_names'])) * 100);
609  $step_data['complete'] = FALSE;
610  }
611  } else {
612  $step_data['percent_done'] = 100;
613  $step_data['complete'] = TRUE;
614  $this->_running_vars['start_job'] = TRUE;
615  }
616 
617  return TRUE;
618 
619  }//end toggleRollbackState()
620 
621 
631  function deleteRollbackEntries(&$step_data, $prefix)
632  {
633  if (!empty($this->_running_vars['purge_rb_date'])) {
634  if ($this->_running_vars['start_job']) {
635  $this->_running_vars['start_job'] = FALSE;
636  $this->_running_vars['to_check'] = $this->_running_vars['rollback_table_names'];
637  }
638 
639  reset($this->_running_vars['to_check']);
640  list($key, $table_name) = each($this->_running_vars['to_check']);
641  unset($this->_running_vars['to_check'][$key]);
642 
643  // Delete rollback entries from the specified table
644  $step_data['message'] = translate('hipo_job_rollback_deleting_rb_entries_from', $table_name);
645  $affected_rows = delete_rollback_entries($table_name, $this->_running_vars['purge_rb_date']);
646 
647  // No more tables? Then we're done!
648  if (empty($this->_running_vars['to_check'])) {
649  $step_data['percent_done'] = 100;
650  $step_data['complete'] = TRUE;
651  $this->_running_vars['start_job'] = TRUE;
652  } else {
653  // Report the correct percentage before proceeding with this step
654  $step_data['percent_done'] = (int)(((count($this->_running_vars['rollback_table_names']) - count($this->_running_vars['to_check'])) / count($this->_running_vars['rollback_table_names'])) * 100);
655 
656  $step_data['complete'] = FALSE;
657  }
658  } else {
659  $step_data['percent_done'] = 100;
660  $step_data['complete'] = TRUE;
661  $this->_running_vars['start_job'] = TRUE;
662  }
663 
664  return TRUE;
665 
666  }//end deleteRollbackEntries()
667 
668 
678  function alignRollbackEntries(&$step_data, $prefix)
679  {
680  if (!empty($this->_running_vars['purge_rb_date'])) {
681  if ($this->_running_vars['start_job']) {
682  $this->_running_vars['start_job'] = FALSE;
683  $this->_running_vars['to_check'] = $this->_running_vars['rollback_table_names'];
684  }
685 
686  reset($this->_running_vars['to_check']);
687  list($key, $table_name) = each($this->_running_vars['to_check']);
688  unset($this->_running_vars['to_check'][$key]);
689 
690  // Align rollback entries in the specified table
691  $affected_rows = align_rollback_entries($table_name, $this->_running_vars['purge_rb_date']);
692  $step_data['message'] = translate('hipo_job_rollback_aligning_rb_entries_in', $table_name);
693 
694  // No more tables? Then we're done!
695  if (empty($this->_running_vars['to_check'])) {
696  $step_data['percent_done'] = 100;
697  $step_data['complete'] = TRUE;
698  $this->_running_vars['start_job'] = TRUE;
699  } else {
700  // Report the correct percentage before proceeding with this step
701  $step_data['percent_done'] = (int)(((count($this->_running_vars['rollback_table_names']) - count($this->_running_vars['to_check'])) / count($this->_running_vars['rollback_table_names'])) * 100);
702 
703  $step_data['complete'] = FALSE;
704  }
705  } else {
706  $step_data['percent_done'] = 100;
707  $step_data['complete'] = TRUE;
708  $this->_running_vars['start_job'] = TRUE;
709  }
710 
711  return TRUE;
712 
713  }//end alignRollbackEntries()
714 
715 
725  function deleteRedundantRollbackEntries(&$step_data, $prefix)
726  {
727  if (!empty($this->_running_vars['delete_redundant_entries'])) {
728  if ($this->_running_vars['start_job']) {
729  $this->_running_vars['start_job'] = FALSE;
730  $this->_running_vars['to_check'] = $this->_running_vars['rollback_table_names'];
731  }
732 
733  if (!empty($this->_running_vars['to_check'])) {
734  reset($this->_running_vars['to_check']);
735  list($key, $table_name) = each($this->_running_vars['to_check']);
736  unset($this->_running_vars['to_check'][$key]);
737 
738  $step_data['message'] = translate('hipo_job_rollback_delete_redundant_rb_entries_in', $table_name);
739  delete_redundant_rollback_entries($table_name);
740  }
741 
742 
743  if (empty($this->_running_vars['to_check'])) {
744  $step_data['percent_done'] = 100;
745  $step_data['complete'] = TRUE;
746  $this->_running_vars['start_job'] = TRUE;
747  } else {
748  $step_data['percent_done'] = (int)(((count($this->_running_vars['rollback_table_names']) - count($this->_running_vars['to_check'])) / count($this->_running_vars['rollback_table_names'])) * 100);
749  $step_data['complete'] = FALSE;
750  }
751  } else {
752  $step_data['percent_done'] = 100;
753  $step_data['complete'] = TRUE;
754  $this->_running_vars['start_job'] = TRUE;
755  }
756 
757  return TRUE;
758 
759  }//end deleteRedundantRollbackEntries()
760 
761 
771  function completeTransaction(&$step_data, $prefix)
772  {
773  $step_data['percent_done'] = 100;
774  $step_data['complete'] = TRUE;
775 
776  // Transaction processed
777  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
778  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
779 
780  return TRUE;
781 
782  }//end completeTransaction()
783 
784 
785 }//end class
786 ?>