move code up one directory
[atutor.git] / install / include / classes / sqlutility.php
1 <?php
2
3
4 class SqlUtility
5 {
6         /**
7         * Function from phpMyAdmin (http://phpwizard.net/projects/phpMyAdmin/)
8         *
9         * Removes comment and splits large sql files into individual queries
10         *
11         * Last revision: September 23, 2001 - gandon
12         *
13         * @param   array    the splitted sql commands
14         * @param   string   the sql commands
15         * @return  boolean  always true
16         * @access  public
17         */
18         function splitSqlFile(&$ret, $sql)
19         {
20                 $sql               = trim($sql);
21                 $sql_len           = strlen($sql);
22                 $char              = '';
23         $string_start      = '';
24         $in_string         = false;
25
26         for ($i = 0; $i < $sql_len; ++$i) {
27                 $char = $sql[$i];
28
29            // We are in a string, check for not escaped end of
30                    // strings except for backquotes that can't be escaped
31            if ($in_string) {
32                         for (;;) {
33                         $i         = strpos($sql, $string_start, $i);
34                                         // No end of string found -> add the current
35                                         // substring to the returned array
36                         if (!$i) {
37                                                 $ret[] = $sql;
38                         return true;
39                         }
40                                         // Backquotes or no backslashes before 
41                                         // quotes: it's indeed the end of the 
42                                         // string -> exit the loop
43                         else if ($string_start == '`' || $sql[$i-1] != '\\') {
44                                                 $string_start      = '';
45                                 $in_string         = false;
46                         break;
47                         }
48                         // one or more Backslashes before the presumed 
49                                         // end of string...
50                         else {
51                                                 // first checks for escaped backslashes
52                         $j                     = 2;
53                         $escaped_backslash     = false;
54                                                 while ($i-$j > 0 && $sql[$i-$j] == '\\') {
55                                                         $escaped_backslash = !$escaped_backslash;
56                                 $j++;
57                         }
58                         // ... if escaped backslashes: it's really the 
59                                                 // end of the string -> exit the loop
60                         if ($escaped_backslash) {
61                                                         $string_start  = '';
62                                 $in_string     = false;
63                                                         break;
64                         }
65                         // ... else loop
66                         else {
67                                                         $i++;
68                         }
69                         } // end if...elseif...else
70                 } // end for
71                 } // end if (in string)
72                 // We are not in a string, first check for delimiter...
73                 else if ($char == ';') {
74                                 // if delimiter found, add the parsed part to the returned array
75                 $ret[]    = substr($sql, 0, $i);
76                 $sql      = ltrim(substr($sql, min($i + 1, $sql_len)));
77                         $sql_len  = strlen($sql);
78                 if ($sql_len) {
79                                         $i      = -1;
80                 } else {
81                         // The submited statement(s) end(s) here
82                         return true;
83                                 }
84                 } // end else if (is delimiter)
85                 // ... then check for start of a string,...
86                 else if (($char == '"') || ($char == '\'') || ($char == '`')) {
87                                 $in_string    = true;
88                                 $string_start = $char;
89                 } // end else if (is start of string)
90
91                 // for start of a comment (and remove this comment if found)...
92                 else if ($char == '#' || ($char == ' ' && $i > 1 && $sql[$i-2] . $sql[$i-1] == '--')) {
93                 // starting position of the comment depends on the comment type
94                         $start_of_comment = (($sql[$i] == '#') ? $i : $i-2);
95                 // if no "\n" exits in the remaining string, checks for "\r"
96                 // (Mac eol style)
97                         $end_of_comment   = (strpos(' ' . $sql, "\012", $i+2))
98                               ? strpos(' ' . $sql, "\012", $i+2)
99                               : strpos(' ' . $sql, "\015", $i+2);
100                         if (!$end_of_comment) {
101                 // no eol found after '#', add the parsed part to the returned
102                 // array and exit
103                         $ret[]   = trim(substr($sql, 0, $i-1));
104                         return true;
105                                 } else {
106                         $sql     = substr($sql, 0, $start_of_comment) . ltrim(substr($sql, $end_of_comment));
107                         $sql_len = strlen($sql);
108                         $i--;
109                 } // end if...else
110                 } // end else if (is comment)
111         } // end for
112
113         // add any rest to the returned array
114         if (!empty($sql) && trim($sql) != '') {
115                         $ret[] = $sql;
116         }
117         return true;
118         }
119
120         /**
121          * add a prefix.'_' to all tablenames in a query
122      * 
123      * @param   string  $query  valid MySQL query string
124      * @param   string  $prefix prefix to add to all table names
125          * @return  mixed   FALSE on failure
126          */
127         function prefixQuery($query, $prefix)
128         {
129                 $pattern = "/^(INSERT INTO|REPLACE INTO|CREATE TABLE|ALTER TABLE|UPDATE)(\s)+([`]?)([^`\s]+)\\3(\s)+/siU";
130                 $pattern2 = "/^(DROP TABLE)(\s)+([`]?)([^`\s]+)\\3(\s)?$/siU";
131                 if (preg_match($pattern, $query, $matches) || preg_match($pattern2, $query, $matches)) {
132                         $replace = "\\1 ".$prefix."\\4\\5";
133                         $matches[0] = preg_replace($pattern, $replace, $query);
134
135                         if ($matches[1] == 'INSERT INTO') {
136                                 $parts = explode(' ', $matches[0]);
137                                 $size_of_parts = count($parts);
138                                 if ($parts[$size_of_parts-2] == 'FROM') {
139                                         $parts[$size_of_parts-1] = $prefix . str_replace('`', '', $parts[$size_of_parts-1]);
140                                         $matches[0] = implode(' ', $parts);
141                                 }
142                         } else if ($matches[1] == 'ALTER TABLE') {
143                                 $parts = explode(' ', $matches[0]);
144                                 if ($parts[3] == 'RENAME') {
145                                         $parts[4] = $prefix . str_replace('`', '', $parts[4]);
146                                         $matches[0] = implode(' ', $parts);
147                                 }
148                         }
149
150                         return $matches;
151                 }
152                 return false;
153         }
154 }
155 ?>