xref: /plugin/sqlite/Tools.php (revision a7a40fb292e55f99ed1ae34981feed1314e2696b)
18da7d805SAndreas Gohr<?php
28da7d805SAndreas Gohr
38da7d805SAndreas Gohrnamespace dokuwiki\plugin\sqlite;
48da7d805SAndreas Gohr
5*a7a40fb2SAnna Dabrowskaclass Tools
6*a7a40fb2SAnna Dabrowska{
78da7d805SAndreas Gohr    /**
88da7d805SAndreas Gohr     * Split sql queries on semicolons, unless when semicolons are quoted
98da7d805SAndreas Gohr     *
108da7d805SAndreas Gohr     * Usually you don't need this. It's only really needed if you need individual results for
118da7d805SAndreas Gohr     * multiple queries. For example in the admin interface.
128da7d805SAndreas Gohr     *
138da7d805SAndreas Gohr     * @param string $sql
148da7d805SAndreas Gohr     * @return string[] sql queries
158da7d805SAndreas Gohr     */
16*a7a40fb2SAnna Dabrowska    public static function SQLstring2array($sql)
17*a7a40fb2SAnna Dabrowska    {
18*a7a40fb2SAnna Dabrowska        $statements = [];
198da7d805SAndreas Gohr        $len = strlen($sql);
208da7d805SAndreas Gohr
218da7d805SAndreas Gohr        // Simple state machine to "parse" sql into single statements
228da7d805SAndreas Gohr        $in_str = false;
238da7d805SAndreas Gohr        $in_com = false;
248da7d805SAndreas Gohr        $statement = '';
258da7d805SAndreas Gohr        for ($i = 0; $i < $len; $i++) {
268da7d805SAndreas Gohr            $prev = $i ? $sql[$i - 1] : "\n";
278da7d805SAndreas Gohr            $char = $sql[$i];
288da7d805SAndreas Gohr            $next = $i < ($len - 1) ? $sql[$i + 1] : '';
298da7d805SAndreas Gohr
308da7d805SAndreas Gohr            // in comment? ignore everything until line end
318da7d805SAndreas Gohr            if ($in_com) {
328da7d805SAndreas Gohr                if ($char == "\n") {
338da7d805SAndreas Gohr                    $in_com = false;
348da7d805SAndreas Gohr                }
358da7d805SAndreas Gohr                continue;
368da7d805SAndreas Gohr            }
378da7d805SAndreas Gohr
388da7d805SAndreas Gohr            // handle strings
398da7d805SAndreas Gohr            if ($in_str) {
408da7d805SAndreas Gohr                if ($char == "'") {
418da7d805SAndreas Gohr                    if ($next == "'") {
428da7d805SAndreas Gohr                        // current char is an escape for the next
438da7d805SAndreas Gohr                        $statement .= $char . $next;
448da7d805SAndreas Gohr                        $i++;
458da7d805SAndreas Gohr                        continue;
468da7d805SAndreas Gohr                    } else {
478da7d805SAndreas Gohr                        // end of string
488da7d805SAndreas Gohr                        $statement .= $char;
498da7d805SAndreas Gohr                        $in_str = false;
508da7d805SAndreas Gohr                        continue;
518da7d805SAndreas Gohr                    }
528da7d805SAndreas Gohr                }
538da7d805SAndreas Gohr                // still in string
548da7d805SAndreas Gohr                $statement .= $char;
558da7d805SAndreas Gohr                continue;
568da7d805SAndreas Gohr            }
578da7d805SAndreas Gohr
588da7d805SAndreas Gohr            // new comment?
598da7d805SAndreas Gohr            if ($char == '-' && $next == '-' && $prev == "\n") {
608da7d805SAndreas Gohr                $in_com = true;
618da7d805SAndreas Gohr                continue;
628da7d805SAndreas Gohr            }
638da7d805SAndreas Gohr
648da7d805SAndreas Gohr            // new string?
658da7d805SAndreas Gohr            if ($char == "'") {
668da7d805SAndreas Gohr                $in_str = true;
678da7d805SAndreas Gohr                $statement .= $char;
688da7d805SAndreas Gohr                continue;
698da7d805SAndreas Gohr            }
708da7d805SAndreas Gohr
718da7d805SAndreas Gohr            // the real delimiter
728da7d805SAndreas Gohr            if ($char == ';') {
738da7d805SAndreas Gohr                $statements[] = trim($statement);
748da7d805SAndreas Gohr                $statement = '';
758da7d805SAndreas Gohr                continue;
768da7d805SAndreas Gohr            }
778da7d805SAndreas Gohr
788da7d805SAndreas Gohr            // some standard query stuff
798da7d805SAndreas Gohr            $statement .= $char;
808da7d805SAndreas Gohr        }
818da7d805SAndreas Gohr        if ($statement) $statements[] = trim($statement);
828da7d805SAndreas Gohr
83a4f75120SAndreas Gohr        return array_filter($statements); // remove empty statements
848da7d805SAndreas Gohr    }
858da7d805SAndreas Gohr}
86