/modules/stabilize/database.php

https://github.com/dionyziz/blogcube · PHP · 258 lines · 204 code · 21 blank · 33 comment · 80 complexity · caee6f43f41076999db2766e0c654497 MD5 · raw file

  1. <?php
  2. /*
  3. Module: Database stabilization
  4. File: /modules/stabilize/database.php
  5. Developers: dionyziz, feedWARd
  6. */
  7. function CompareFields($field1,$field2) {
  8. if ( $field1->Name() != $field2->Name() ) return false;
  9. if ( $field1->Type() != $field2->Type() ) return false;
  10. if ( $field1->IsNull() != $field2->IsNull() ) return false;
  11. if ( $field1->GetKey() != $field2->GetKey() ) return false;
  12. if ( $field1->DefaultValue() != $field2->DefaultValue() ) return false;
  13. if ( $field1->Extra() != $field2->Extra() ) return false;
  14. if ( $field1->Type() == "ENUM" ) {
  15. if ($field1->GetAllEnums() != $field2->GetAllEnums()) return false;
  16. }
  17. return true;
  18. }
  19. function DescribeField($curfield,$showprkey = false,$prinquery = false) {
  20. $curquery = " `" . $curfield->Name() . "`";
  21. $isprimary = false;
  22. $curquery .= " " . $curfield->Type();
  23. if ( $curfield->Type() == "ENUM" ) {
  24. $curquery .= "(";
  25. while(($curenum = $curfield->GetEnum()) !== false) {
  26. $curquery .= "'" . $curenum . "',";
  27. }
  28. $curquery = substr($curquery,0,-1);
  29. $curquery .= ")";
  30. }
  31. if ( $curfield->IsNull() != "YES" ) $curquery .= " NOT NULL";
  32. if ( $curfield->DefaultValue() != null ) $curquery .= " default '" . $curfield->DefaultValue() . "'";
  33. if ( $curfield->Extra() ) $curquery .= " " . $curfield->Extra();
  34. if ( $curfield->GetKey() == "PRI" ) {
  35. $isprimary = true;
  36. if ( $prinquery == true ) $curquery .= " PRIMARY KEY";
  37. }
  38. //return values
  39. if (( $showprkey == true ) && ( $prinquery == false )) {
  40. return array($curquery,$isprimary);
  41. }
  42. else {
  43. return $curquery;
  44. }
  45. }
  46. function CompareTables($table1,$table2) {
  47. $s = FieldLCS($table1,$table2);
  48. $i = 0;
  49. $all = count($s);
  50. $queries = Array();
  51. $cur = "";
  52. $curquery = "";
  53. while ( $curfield = $table2->GetField() ) {
  54. if ( $i >= count($s) ) { $queries[] = "ALTER TABLE `" . $table2->Name() . "` DROP `" . $curfield->Name() . "`;"; }
  55. else if ( CompareFields($curfield,$s[$i]) == true ) {
  56. $i++;
  57. }
  58. else {
  59. $queries[] = "ALTER TABLE `" . $table2->Name() . "` DROP `" . $curfield->Name() . "`;";
  60. }
  61. }
  62. $i = 0;
  63. while ( $curfield = $table1->GetField() ) {
  64. if ( $i >= count($s) ) {
  65. $curquery = "ALTER TABLE `" . $table2->Name() . "` ADD " . DescribeField($curfield,true,true);
  66. if ( $cur == "" ) $curquery .= " FIRST;";
  67. else $curquery .= " AFTER `" . $cur . "`;";
  68. $queries[] = $curquery;
  69. $cur = $curfield->Name();
  70. }
  71. else if ( CompareFields($curfield,$s[$i]) == true ) {
  72. $cur = $s[$i]->Name();
  73. $i++;
  74. }
  75. else {
  76. $curquery = "ALTER TABLE `" . $table2->Name() . "` ADD " . DescribeField($curfield,true,true);
  77. if ( $cur == "" ) $curquery .= " FIRST;";
  78. else $curquery .= " AFTER `" . $cur . "`;";
  79. $queries[] = $curquery;
  80. $cur = $curfield->Name();
  81. }
  82. }
  83. return $queries;
  84. }
  85. define('LCS_OK', 0);
  86. define('LCS_LEFT', 1);
  87. define('LCS_UP', 2);
  88. function FieldLCS($table1, $table2) {
  89. /*
  90. blame dionyziz
  91. */
  92. $x = Array();
  93. $y = Array();
  94. while ($curfield = $table1->GetField()) {
  95. $x[] = $curfield;
  96. }
  97. while ($curfield = $table2->GetField()) {
  98. $y[] = $curfield;
  99. }
  100. $m = count($x);
  101. $n = count($y);
  102. // $c is a two-dimentional array which will store the length of the LCS
  103. // between the two left-most substrings of $x and $y of length $i and $j
  104. // so $c[$i][$j] = strlen(LCS(substr($x, 0, $i), substr($y, 0, $j))) if that makes any sense
  105. // $b is again a two-dimentional array which will store the path we have to
  106. // follow in order to construct the LCS we are building inside our two strings
  107. // we are constructing the LCS _backwards_
  108. // in simple words, LCS_OK means include this character and move backwards in both strings
  109. // while LCS_LEFT and LCS_UP means move backwards only in one of the two strings and do
  110. // not any character (since it's not a common character)
  111. // initialize the arrays, make them two-dimentional
  112. // in addition, set to zero the length of LCS between zero-length strings (trivially)
  113. $c = Array();
  114. $c = array_fill(0, $m + 1, array(0)); // $c[$i][0] = 0; for every $i
  115. $c[0] = array_fill(0, $n + 1, 0); // $c[0][$j] = 0; for every $j
  116. // go through the two stings character-by-character to construct the two arrays
  117. for ($i = 1; $i <= $m; ++$i) {
  118. for ($j = 1; $j <= $n; ++$j) {
  119. // if a given character is the same, append it to the LCS
  120. if (CompareFields($x[$i - 1],$y[$j-1]) == true) {
  121. // the new LCS is going to be as long as the previous plus one character
  122. $c[$i][$j] = $c[$i - 1][$j - 1] + 1;
  123. // this is a character of the LCS
  124. $b[$i][$j] = LCS_OK;
  125. }
  126. // the character is not the same, we have to compare the lengths of the two possible sub-LCSs
  127. // and use the greater one (since we want to construct as long a string as possible)
  128. else if ($c[$i - 1][$j] >= $c[$i][$j - 1]) {
  129. // skip one character upwards
  130. $c[$i][$j] = $c[$i - 1][$j];
  131. $b[$i][$j] = LCS_UP;
  132. }
  133. else {
  134. // skip one character leftwards
  135. $c[$i][$j] = $c[$i][$j - 1];
  136. $b[$i][$j] = LCS_LEFT;
  137. }
  138. }
  139. }
  140. // now all we need is to go through the $b table to make the final string
  141. $i = $m;
  142. $j = $n;
  143. $l = array();
  144. while ($i != 0 && $j != 0) {
  145. switch ($b[$i][$j]) {
  146. case LCS_OK:
  147. --$i; // decrementing before using, so we don't need to make it -1 inside the {}
  148. $l[] = $x[$i];
  149. ++$cnt;
  150. //fallthrough
  151. case LCS_LEFT:
  152. --$j;
  153. break;
  154. case LCS_UP:
  155. --$i;
  156. break;
  157. }
  158. }
  159. $l = array_reverse($l);
  160. return $l;
  161. }
  162. function StabilizeDatabase() {
  163. global $db_access;
  164. $beta_access = $db_access[ 'unstable_stabilize' ];
  165. $stable_access = $db_access[ 'stable_stabilize' ];
  166. $queries = array();
  167. if ( !isset( $beta_access ) || !isset( $stable_access ) ) {
  168. bc_die( 'Stabilization: Could not read access codes to databases' );
  169. }
  170. $beta_database = New BCDatabase(
  171. 'localhost' ,
  172. $beta_access[ 'username' ] ,
  173. $beta_access[ 'password' ] ,
  174. $beta_access[ 'db' ]
  175. );
  176. $stable_database = New BCDatabase(
  177. 'localhost' ,
  178. $stable_access[ 'username' ] ,
  179. $stable_access[ 'password' ] ,
  180. $stable_access[ 'db' ]
  181. );
  182. if ( !$stable_database->Connect() ) {
  183. bc_die( 'Stabilization: Connection to Stable failed: ' . $stable_database->Error() );
  184. }
  185. if ( !$beta_database->Connect() ) {
  186. bc_die( 'Stabilization: Connection to Beta failed: ' . $beta_database->Error() );
  187. }
  188. $stable_table_list = $stable_database->GetTables();
  189. $beta_table_list = $beta_database->GetTables();
  190. $stable_table_names = array();
  191. for($i=0;$i<count($stable_table_list);$i++) {
  192. $stable_table_names[] = $stable_table_list[$i]->Name();
  193. }
  194. $beta_table_names = array();
  195. for($i=0;$i<count($beta_table_list);$i++) {
  196. $beta_table_names[] = $beta_table_list[$i]->Name();
  197. }
  198. //drop tables
  199. $todrop = array_diff($stable_table_names,$beta_table_names);
  200. $curquery = "";
  201. foreach($todrop as $ctablename) {
  202. if ( $curquery == "" ) $curquery = "DROP TABLE `" . $ctablename . "`";
  203. else $curquery .= ",`" . $ctablename . "`";
  204. }
  205. if ( $curquery != "" ) {
  206. $curquery .= ";";
  207. $queries[] = $curquery;
  208. }
  209. //create tables
  210. $tocreate = array_diff($beta_table_names,$stable_table_names);
  211. foreach($tocreate as $ctablename) {
  212. $curtable = New BCDbTable($ctablename,$beta_database);
  213. $curquery = "CREATE TABLE `" . $ctablename . "` (";
  214. $curprkey = "";
  215. while ($curfield = $curtable->GetField()) {
  216. $curquery .= "\n";
  217. $curres = DescribeField($curfield,true);
  218. $curquery .= $curres[0];
  219. if ( $curres[1] == true ) $curprkey = $curfield->Name();
  220. $curquery .= ",";
  221. }
  222. if ( $curprkey != "" ) $curquery .= "\n PRIMARY KEY ( `" . $curprkey . "` ),";
  223. $curquery = substr($curquery,0,-1);
  224. $curquery .= "\n);\n";
  225. $queries[] = $curquery;
  226. }
  227. //alter tables
  228. $toalter = array_intersect($beta_table_names,$stable_table_names);
  229. foreach($toalter as $ctablename) {
  230. $firsttable = New BCDbTable($ctablename,$beta_database);
  231. $secondtable = New BCDbTable($ctablename,$stable_database);
  232. $alterqueries = CompareTables($firsttable,$secondtable);
  233. $queries = array_merge($queries,$alterqueries);
  234. }
  235. return $queries;
  236. }
  237. ?>