Changeset 319

Show
Ignore:
Timestamp:
12/14/07 16:40:38 (7 months ago)
Author:
hans
Message:

Fixes #198 - Adding the superior, regexp-based algorythm from Propel's PropelSQLExec to handle multi-line SQL statements.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/2.3/classes/phing/tasks/ext/pdo/PDOSQLExecTask.php

    r260 r319  
    373373    public function runStatements(Reader $reader) { 
    374374        $sql = ""; 
    375         $line = ""; 
    376         $in = new BufferedReader($reader); 
    377         try { 
    378                 while (($line = $in->readLine()) !== null) { 
    379                         $line = trim($line); 
    380                         $line = ProjectConfigurator::replaceProperties($this->project, $line, 
    381                         $this->project->getProperties()); 
    382  
    383                         if (StringHelper::startsWith("//", $line) || 
    384                         StringHelper::startsWith("--", $line) || 
    385                         StringHelper::startsWith("#", $line)) { 
    386                                 continue; 
    387                         } 
    388  
    389                         if (strlen($line) > 4 
    390                         && strtoupper(substr($line,0, 4)) == "REM ") { 
    391                                 continue; 
    392                         } 
    393  
    394                         $sql .= " " . $line; 
    395                         $sql = trim($sql); 
    396  
    397                         // SQL defines "--" as a comment to EOL 
    398                         // and in Oracle it may contain a hint 
    399                         // so we cannot just remove it, instead we must end it 
    400                         if (strpos($line, "--") !== false) { 
    401                                 $sql .= "\n"; 
    402                         } 
    403  
    404                         if ($this->delimiterType == self::DELIM_NORMAL 
    405                         && StringHelper::endsWith($this->delimiter, $sql) 
    406                         || $this->delimiterType == self::DELIM_ROW 
    407                         && $line == $this->delimiter) { 
    408                                 $this->log("SQL: " . $sql, Project::MSG_VERBOSE); 
    409                                 $this->execSQL(StringHelper::substring($sql, 0, strlen($sql) - strlen($this->delimiter) - 1)); 
    410                                 $sql = ""; 
    411                         } 
    412                 } 
    413  
    414                 // Catch any statements not followed by ; 
    415                 if ($sql !== "") { 
    416                         $this->execSQL($sql); 
    417                 } 
    418         } catch (PDOException $e) { 
    419                 throw new BuildException("Error running statements", $e); 
    420         } 
     375                $line = ""; 
     376                $sqlBacklog = ""; 
     377                $hasQuery = false; 
     378 
     379                $in = new BufferedReader($reader); 
     380 
     381                try { 
     382                        while (($line = $in->readLine()) !== null) { 
     383                                $line = trim($line); 
     384                                $line = ProjectConfigurator::replaceProperties($this->project, $line, 
     385                                                $this->project->getProperties()); 
     386 
     387                                if (StringHelper::startsWith("//", $line) || 
     388                                        StringHelper::startsWith("--", $line) || 
     389                                        StringHelper::startsWith("#", $line)) { 
     390                                        continue; 
     391                                } 
     392 
     393                                if (strlen($line) > 4 
     394                                                && strtoupper(substr($line,0, 4)) == "REM ") { 
     395                                        continue; 
     396                                } 
     397 
     398                                if ($sqlBacklog !== "") { 
     399                                        $sql = $sqlBacklog; 
     400                                        $sqlBacklog = ""; 
     401                                } 
     402 
     403                                $sql .= " " . $line . "\n"; 
     404 
     405                                // SQL defines "--" as a comment to EOL 
     406                                // and in Oracle it may contain a hint 
     407                                // so we cannot just remove it, instead we must end it 
     408                                if (strpos($line, "--") !== false) { 
     409                                        $sql .= "\n"; 
     410                                } 
     411 
     412                                // DELIM_ROW doesn't need this (as far as i can tell) 
     413                                if ($this->delimiterType == self::DELIM_NORMAL) { 
     414 
     415                                        $reg = "#((?:\"(?:\\\\.|[^\"])*\"?)+|'(?:\\\\.|[^'])*'?|" . preg_quote($this->delimiter) . ")#"; 
     416 
     417                                        $sqlParts = preg_split($reg, $sql, 0, PREG_SPLIT_DELIM_CAPTURE); 
     418                                        $sqlBacklog = ""; 
     419                                        foreach ($sqlParts as $sqlPart) { 
     420                                                // we always want to append, even if it's a delim (which will be stripped off later) 
     421                                                $sqlBacklog .= $sqlPart; 
     422 
     423                                                // we found a single (not enclosed by ' or ") delimiter, so we can use all stuff before the delim as the actual query 
     424                                                if ($sqlPart === $this->delimiter) { 
     425                                                        $sql = $sqlBacklog; 
     426                                                        $sqlBacklog = ""; 
     427                                                        $hasQuery = true; 
     428                                                } 
     429                                        } 
     430                                } 
     431 
     432                                if ($hasQuery || ($this->delimiterType == self::DELIM_ROW && $line == $this->delimiter)) { 
     433                                        // this assumes there is always a delimter on the end of the SQL statement. 
     434                                        $sql = StringHelper::substring($sql, 0, strlen($sql) - 1 - strlen($this->delimiter)); 
     435                                        $this->log("SQL: " . $sql, PROJECT_MSG_VERBOSE); 
     436                                        $this->execSQL($sql); 
     437                                        $sql = ""; 
     438                                        $hasQuery = false; 
     439                                } 
     440                        } 
     441 
     442                        // Catch any statements not followed by ; 
     443                        if ($sql !== "") { 
     444                                $this->execSQL($sql); 
     445                        } 
     446                } catch (PDOException $e) { 
     447                        throw $e; 
     448                } 
    421449    } 
    422450