PageRenderTime 50ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/setup/parser.php

https://github.com/hegylako/openTracker
PHP | 151 lines | 91 code | 28 blank | 32 comment | 24 complexity | 008dd0fecfcaaef44802fbeca86b18e0 MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. class Parser {
  3. private $query;
  4. function __construct($file) {
  5. $this->query = file_get_contents($file);
  6. $this->query = $this->remove_remarks($this->query);
  7. $this->query = $this->split_sql_file($this->query, ';');
  8. }
  9. function parse(){
  10. return $this->query;
  11. }
  12. function remove_comments(&$output) {
  13. $lines = explode("\n", $output);
  14. $output = "";
  15. // try to keep mem. use down
  16. $linecount = count($lines);
  17. $in_comment = false;
  18. for ($i = 0; $i < $linecount; $i++) {
  19. if (preg_match("/^\/\*/", preg_quote($lines[$i]))) {
  20. $in_comment = true;
  21. }
  22. if (!$in_comment) {
  23. $output .= $lines[$i] . "\n";
  24. }
  25. if (preg_match("/\*\/$/", preg_quote($lines[$i]))) {
  26. $in_comment = false;
  27. }
  28. }
  29. unset($lines);
  30. return $output;
  31. }
  32. //
  33. // remove_remarks will strip the sql comment lines out of an uploaded sql file
  34. //
  35. function remove_remarks($sql) {
  36. $lines = explode("\n", $sql);
  37. // try to keep mem. use down
  38. $sql = "";
  39. $linecount = count($lines);
  40. $output = "";
  41. for ($i = 0; $i < $linecount; $i++) {
  42. if (($i != ($linecount - 1)) || (strlen($lines[$i]) > 0)) {
  43. if (isset($lines[$i][0]) && $lines[$i][0] != "#") {
  44. $output .= $lines[$i] . "\n";
  45. } else {
  46. $output .= "\n";
  47. }
  48. // Trading a bit of speed for lower mem. use here.
  49. $lines[$i] = "";
  50. }
  51. }
  52. return $output;
  53. }
  54. //
  55. // split_sql_file will split an uploaded sql file into single sql statements.
  56. // Note: expects trim() to have already been run on $sql.
  57. //
  58. function split_sql_file($sql, $delimiter) {
  59. // Split up our string into "possible" SQL statements.
  60. $tokens = explode($delimiter, $sql);
  61. // try to save mem.
  62. $sql = "";
  63. $output = array();
  64. // we don't actually care about the matches preg gives us.
  65. $matches = array();
  66. // this is faster than calling count($oktens) every time thru the loop.
  67. $token_count = count($tokens);
  68. for ($i = 0; $i < $token_count; $i++) {
  69. // Don't wanna add an empty string as the last thing in the array.
  70. if (($i != ($token_count - 1)) || (strlen($tokens[$i] > 0))) {
  71. // This is the total number of single quotes in the token.
  72. $total_quotes = preg_match_all("/'/", $tokens[$i], $matches);
  73. // Counts single quotes that are preceded by an odd number of backslashes,
  74. // which means they're escaped quotes.
  75. $escaped_quotes = preg_match_all("/(?<!\\\\)(\\\\\\\\)*\\\\'/", $tokens[$i], $matches);
  76. $unescaped_quotes = $total_quotes - $escaped_quotes;
  77. // If the number of unescaped quotes is even, then the delimiter did NOT occur inside a string literal.
  78. if (($unescaped_quotes % 2) == 0) {
  79. // It's a complete sql statement.
  80. $output[] = $tokens[$i];
  81. // save memory.
  82. $tokens[$i] = "";
  83. } else {
  84. // incomplete sql statement. keep adding tokens until we have a complete one.
  85. // $temp will hold what we have so far.
  86. $temp = $tokens[$i] . $delimiter;
  87. // save memory..
  88. $tokens[$i] = "";
  89. // Do we have a complete statement yet?
  90. $complete_stmt = false;
  91. for ($j = $i + 1; (!$complete_stmt && ($j < $token_count)); $j++) {
  92. // This is the total number of single quotes in the token.
  93. $total_quotes = preg_match_all("/'/", $tokens[$j], $matches);
  94. // Counts single quotes that are preceded by an odd number of backslashes,
  95. // which means they're escaped quotes.
  96. $escaped_quotes = preg_match_all("/(?<!\\\\)(\\\\\\\\)*\\\\'/", $tokens[$j], $matches);
  97. $unescaped_quotes = $total_quotes - $escaped_quotes;
  98. if (($unescaped_quotes % 2) == 1) {
  99. // odd number of unescaped quotes. In combination with the previous incomplete
  100. // statement(s), we now have a complete statement. (2 odds always make an even)
  101. $output[] = $temp . $tokens[$j];
  102. // save memory.
  103. $tokens[$j] = "";
  104. $temp = "";
  105. // exit the loop.
  106. $complete_stmt = true;
  107. // make sure the outer loop continues at the right point.
  108. $i = $j;
  109. } else {
  110. // even number of unescaped quotes. We still don't have a complete statement.
  111. // (1 odd and 1 even always make an odd)
  112. $temp .= $tokens[$j] . $delimiter;
  113. // save memory.
  114. $tokens[$j] = "";
  115. }
  116. } // for..
  117. } // else
  118. }
  119. }
  120. return $output;
  121. }
  122. }
  123. ?>