/** * read in lines and execute them * @param Reader $reader * @param null $out * @throws BuildException */ public function runStatements(Reader $reader, $out = null) { $sql = ""; $line = ""; $buffer = ''; if (is_array($this->filterChains) && !empty($this->filterChains)) { $in = FileUtils::getChainedReader(new BufferedReader($reader), $this->filterChains, $this->getProject()); while (-1 !== ($read = $in->read())) { // -1 indicates EOF $buffer .= $read; } $lines = explode("\n", $buffer); } else { $in = new BufferedReader($reader); while (($line = $in->readLine()) !== null) { $lines[] = $line; } } try { foreach ($lines as $line) { $line = trim($line); $line = ProjectConfigurator::replaceProperties($this->project, $line, $this->project->getProperties()); if (StringHelper::startsWith("//", $line) || StringHelper::startsWith("--", $line) || StringHelper::startsWith("#", $line)) { continue; } if (strlen($line) > 4 && strtoupper(substr($line, 0, 4)) == "REM ") { continue; } $sql .= " " . $line; $sql = trim($sql); // SQL defines "--" as a comment to EOL // and in Oracle it may contain a hint // so we cannot just remove it, instead we must end it if (strpos($line, "--") !== false) { $sql .= "\n"; } if ($this->delimiterType == self::DELIM_NORMAL && StringHelper::endsWith($this->delimiter, $sql) || $this->delimiterType == self::DELIM_ROW && $line == $this->delimiter) { $this->log("SQL: " . $sql, Project::MSG_VERBOSE); $this->execSQL(StringHelper::substring($sql, 0, strlen($sql) - strlen($this->delimiter)), $out); $sql = ""; } } // Catch any statements not followed by ; if ($sql !== "") { $this->execSQL($sql, $out); } } catch (SQLException $e) { throw new BuildException("Error running statements", $e); } }
/** * Returns next query from SQL source, null if no more queries left * * In case of "row" delimiter type this searches for strings containing only * delimiters. In case of "normal" delimiter type, this uses simple regular * expression logic to search for delimiters. * * @return string|null */ public function nextQuery() { $sql = ""; $hasQuery = false; while (($line = $this->sqlReader->readLine()) !== null) { $delimiter = $this->parent->getDelimiter(); $project = $this->parent->getOwningTarget()->getProject(); $line = ProjectConfigurator::replaceProperties($project, trim($line), $project->getProperties()); if ($line != $delimiter && (StringHelper::startsWith("//", $line) || StringHelper::startsWith("--", $line) || StringHelper::startsWith("#", $line))) { continue; } if (strlen($line) > 4 && strtoupper(substr($line, 0, 4)) == "REM ") { continue; } // MySQL supports defining new delimiters if (preg_match('/DELIMITER [\'"]?([^\'" $]+)[\'"]?/i', $line, $matches)) { $this->parent->setDelimiter($matches[1]); continue; } if ($this->sqlBacklog !== "") { $sql = $this->sqlBacklog; $this->sqlBacklog = ""; } $sql .= " " . $line . "\n"; // SQL defines "--" as a comment to EOL // and in Oracle it may contain a hint // so we cannot just remove it, instead we must end it if (strpos($line, "--") !== false) { $sql .= "\n"; } // DELIM_ROW doesn't need this (as far as i can tell) if ($this->delimiterType == PDOSQLExecTask::DELIM_NORMAL) { $reg = "#((?:\"(?:\\\\.|[^\"])*\"?)+|'(?:\\\\.|[^'])*'?|" . preg_quote($delimiter) . ")#"; $sqlParts = preg_split($reg, $sql, 0, PREG_SPLIT_DELIM_CAPTURE); $this->sqlBacklog = ""; foreach ($sqlParts as $sqlPart) { // we always want to append, even if it's a delim (which will be stripped off later) $this->sqlBacklog .= $sqlPart; // we found a single (not enclosed by ' or ") delimiter, so we can use all stuff before the delim as the actual query if ($sqlPart === $delimiter) { $sql = $this->sqlBacklog; $this->sqlBacklog = ""; $hasQuery = true; } } } if ($hasQuery || $this->delimiterType == PDOSQLExecTask::DELIM_ROW && $line == $delimiter) { // this assumes there is always a delimter on the end of the SQL statement. $sql = StringHelper::substring($sql, 0, strlen($sql) - strlen($delimiter) - ($this->delimiterType == PDOSQLExecTask::DELIM_ROW ? 2 : 1)); return $sql; } } // Catch any statements not followed by ; if ($sql !== "") { return $sql; } return null; }
/** * This method will parse a string containing ${value} style * property values into two lists. The first list is a collection * of text fragments, while the other is a set of string property names * null entries in the first list indicate a property reference from the * second list. * * This is slower than regex, but useful for this class, which has to handle * multiple parsing passes for properties. * * @param string $value The string to be scanned for property references * @param array &$fragments The found fragments * @param array &$propertyRefs The found refs * @throws BuildException */ protected function parsePropertyString($value, &$fragments, &$propertyRefs) { $prev = 0; $pos = 0; while (($pos = strpos($value, '$', $prev)) !== false) { if ($pos > $prev) { array_push($fragments, StringHelper::substring($value, $prev, $pos - 1)); } if ($pos === strlen($value) - 1) { array_push($fragments, '$'); $prev = $pos + 1; } elseif ($value[$pos + 1] !== '{') { // the string positions were changed to value-1 to correct // a fatal error coming from function substring() array_push($fragments, StringHelper::substring($value, $pos, $pos + 1)); $prev = $pos + 2; } else { $endName = strpos($value, '}', $pos); if ($endName === false) { throw new BuildException("Syntax error in property: {$value}"); } $propertyName = StringHelper::substring($value, $pos + 2, $endName - 1); array_push($fragments, null); array_push($propertyRefs, $propertyName); $prev = $endName + 1; } } if ($prev < strlen($value)) { array_push($fragments, StringHelper::substring($value, $prev)); } }
/** * Read the statements from the .sql file and execute them. * Lines starting with '//', '--' or 'REM ' are ignored. * * Developer note: must be public in order to be called from * sudo-"inner" class PropelSQLExecTransaction. * * @param Reader $reader * @param $out Optional output stream. * @throws SQLException * @throws IOException */ public function runStatements(Reader $reader, $out = null) { $sql = ""; $line = ""; $sqlBacklog = ""; $hasQuery = false; $in = new BufferedReader($reader); try { while (($line = $in->readLine()) !== null) { $line = trim($line); $line = ProjectConfigurator::replaceProperties($this->project, $line, $this->project->getProperties()); if (StringHelper::startsWith("//", $line) || StringHelper::startsWith("--", $line) || StringHelper::startsWith("#", $line)) { continue; } if (strlen($line) > 4 && strtoupper(substr($line, 0, 4)) == "REM ") { continue; } if ($sqlBacklog !== "") { $sql = $sqlBacklog; $sqlBacklog = ""; } $sql .= " " . $line . "\n"; // SQL defines "--" as a comment to EOL // and in Oracle it may contain a hint // so we cannot just remove it, instead we must end it if (strpos($line, "--") !== false) { $sql .= "\n"; } // DELIM_ROW doesn't need this (as far as i can tell) if ($this->delimiterType == self::DELIM_NORMAL) { $reg = "#((?:\"(?:\\\\.|[^\"])*\"?)+|'(?:\\\\.|[^'])*'?|" . preg_quote($this->delimiter) . ")#"; $sqlParts = preg_split($reg, $sql, 0, PREG_SPLIT_DELIM_CAPTURE); $sqlBacklog = ""; foreach ($sqlParts as $sqlPart) { // we always want to append, even if it's a delim (which will be stripped off later) $sqlBacklog .= $sqlPart; // we found a single (not enclosed by ' or ") delimiter, so we can use all stuff before the delim as the actual query if ($sqlPart === $this->delimiter) { $sql = $sqlBacklog; $sqlBacklog = ""; $hasQuery = true; } } } if ($hasQuery || $this->delimiterType == self::DELIM_ROW && $line == $this->delimiter) { // this assumes there is always a delimter on the end of the SQL statement. $sql = StringHelper::substring($sql, 0, strlen($sql) - 1 - strlen($this->delimiter)); $this->log("SQL: " . $sql, PROJECT_MSG_VERBOSE); $this->execSQL($sql, $out); $sql = ""; $hasQuery = false; } } // Catch any statements not followed by ; if ($sql !== "") { $this->execSQL($sql, $out); } } catch (SQLException $e) { throw $e; } }
public static function throwableMessage(&$msg, $error, $verbose) { while ($error instanceof BuildException) { $cause = $error->getCause(); if ($cause === null) { break; } $msg1 = (string) $error; $msg2 = (string) $cause; if (StringHelper::endsWith($msg2, $msg1)) { $msg .= StringHelper::substring($msg1, 0, strlen($msg1) - strlen($msg2)); $error = $cause; } else { break; } } if ($verbose || !$error instanceof BuildException) { $msg .= (string) $error; } else { $msg .= $error->getMessage() . PHP_EOL; } }
/** * Apply this map entry to a given path element * * @param string $elem Path element to process * @return string Updated path element after mapping * * @throws BuildException */ public function apply($elem) { if ($this->outer->from === null || $this->outer->to === null) { throw new BuildException("Both 'from' and 'to' must be set " . "in a map entry"); } // If we're on windows, then do the comparison ignoring case $cmpElem = $this->outer->onWindows ? strtolower($elem) : $elem; $cmpFrom = $this->outer->onWindows ? strtolower(str_replace('/', '\\', $this->outer->from)) : $this->outer->from; // If the element starts with the configured prefix, then // convert the prefix to the configured 'to' value. if (StringHelper::startsWith($cmpFrom, $cmpElem)) { $len = strlen($this->outer->from); if ($len >= strlen($elem)) { $elem = $this->outer->to; } else { $elem = $this->outer->to . StringHelper::substring($elem, $len); } } return $elem; }
/** * Read the statements from the .sql file and execute them. * Lines starting with '//', '--' or 'REM ' are ignored. * * Developer note: must be public in order to be called from * sudo-"inner" class PropelSQLExecTransaction. * * @param Reader $reader * @param $out Optional output stream. * @throws PDOException * @throws IOException */ public function runStatements(Reader $reader, $out = null) { $sql = ""; $line = ""; $sqlBacklog = ""; $hasQuery = false; $in = new BufferedReader($reader); $parser['pointer'] = 0; $parser['isInString'] = false; $parser['stringQuotes'] = ""; $parser['backslashCount'] = 0; $parser['parsedString'] = ""; $sqlParts = array(); while (($line = $in->readLine()) !== null) { $line = trim($line); $line = ProjectConfigurator::replaceProperties($this->project, $line, $this->project->getProperties()); if (StringHelper::startsWith("//", $line) || StringHelper::startsWith("--", $line) || StringHelper::startsWith("#", $line)) { continue; } if (strlen($line) > 4 && strtoupper(substr($line, 0, 4)) == "REM ") { continue; } if ($sqlBacklog !== "") { $sql = $sqlBacklog; $sqlBacklog = ""; } $sql .= " " . $line . PHP_EOL; // SQL defines "--" as a comment to EOL // and in Oracle it may contain a hint // so we cannot just remove it, instead we must end it if (strpos($line, "--") !== false) { $sql .= PHP_EOL; } // DELIM_ROW doesn't need this (as far as i can tell) if ($this->delimiterType == self::DELIM_NORMAL) { // old regex, being replaced due to segfaults: // See: http://propel.phpdb.org/trac/ticket/294 //$reg = "#((?:\"(?:\\\\.|[^\"])*\"?)+|'(?:\\\\.|[^'])*'?|" . preg_quote($this->delimiter) . ")#"; //$sqlParts = preg_split($reg, $sql, 0, PREG_SPLIT_DELIM_CAPTURE); $i = $parser['pointer']; $c = strlen($sql); while ($i < $c) { $char = $sql[$i]; switch ($char) { case "\\": $parser['backslashCount']++; $this->log("c{$i}: found " . $parser['backslashCount'] . " backslash(es)", Project::MSG_VERBOSE); break; case "'": case "\"": if ($parser['isInString'] && $parser['stringQuotes'] == $char) { if (($parser['backslashCount'] & 1) == 0) { #$this->log("$i: out of string", Project::MSG_VERBOSE); $parser['isInString'] = false; } else { $this->log("c{$i}: rejected quoted delimiter", Project::MSG_VERBOSE); } } elseif (!$parser['isInString']) { $parser['stringQuotes'] = $char; $parser['isInString'] = true; #$this->log("$i: into string with $parser['stringQuotes']", Project::MSG_VERBOSE); } break; } if ($char == $this->delimiter && !$parser['isInString']) { $this->log("c{$i}: valid end of command found!", Project::MSG_VERBOSE); $sqlParts[] = $parser['parsedString']; $sqlParts[] = $this->delimiter; break; } $parser['parsedString'] .= $char; if ($char !== "\\") { if ($parser['backslashCount']) { $this->log("{$i}: backslash reset", Project::MSG_VERBOSE); } $parser['backslashCount'] = 0; } $i++; $parser['pointer']++; } $sqlBacklog = ""; foreach ($sqlParts as $sqlPart) { // we always want to append, even if it's a delim (which will be stripped off later) $sqlBacklog .= $sqlPart; // we found a single (not enclosed by ' or ") delimiter, so we can use all stuff before the delim as the actual query if ($sqlPart === $this->delimiter) { $sql = $sqlBacklog; $sqlBacklog = ""; $hasQuery = true; } } } if ($hasQuery || $this->delimiterType == self::DELIM_ROW && $line == $this->delimiter) { // this assumes there is always a delimter on the end of the SQL statement. $sql = StringHelper::substring($sql, 0, strlen($sql) - 1 - strlen($this->delimiter)); $this->log("SQL: " . $sql, Project::MSG_VERBOSE); $this->execSQL($sql, $out); $sql = ""; $hasQuery = false; $parser['pointer'] = 0; $parser['isInString'] = false; $parser['stringQuotes'] = ""; $parser['backslashCount'] = 0; $parser['parsedString'] = ""; $sqlParts = array(); } } // Catch any statements not followed by ; if ($sql !== "") { $this->execSQL($sql, $out); } }
/** * do the work * @throws BuildException if required attributes are not supplied * property and attribute are required attributes */ public function main() { if ($this->property === null) { throw new BuildException("property attribute required", $this->getLocation()); } if ($this->file == null) { throw new BuildException("file attribute required", $this->getLocation()); } $value = $this->file->getName(); if ($this->suffix != null && StringHelper::endsWith($this->suffix, $value)) { // if the suffix does not starts with a '.' and the // char preceding the suffix is a '.', we assume the user // wants to remove the '.' as well $pos = strlen($value) - strlen($this->suffix) - 1; if ($pos > 0 && $this->suffix[0] !== '.' && $value[$pos] === '.') { $pos--; } $value = StringHelper::substring($value, 0, $pos); } $this->getProject()->setNewProperty($this->property, $value); }
/** * read in lines and execute them * @throws SQLException, IOException */ public function runStatements(Reader $reader, $out = null) { $sql = ""; $line = ""; $in = new BufferedReader($reader); try { while (($line = $in->readLine()) !== null) { $line = trim($line); $line = ProjectConfigurator::replaceProperties($this->project, $line, $this->project->getProperties()); if (StringHelper::startsWith("//", $line) || StringHelper::startsWith("--", $line) || StringHelper::startsWith("#", $line)) { continue; } if (strlen($line) > 4 && strtoupper(substr($line, 0, 4)) == "REM ") { continue; } $sql .= " " . $line; $sql = trim($sql); // SQL defines "--" as a comment to EOL // and in Oracle it may contain a hint // so we cannot just remove it, instead we must end it if (strpos($line, "--") !== false) { $sql .= "\n"; } if ($this->delimiterType == self::DELIM_NORMAL && StringHelper::endsWith($this->delimiter, $sql) || $this->delimiterType == self::DELIM_ROW && $line == $this->delimiter) { $this->log("SQL: " . $sql, PROJECT_MSG_VERBOSE); $this->execSQL(StringHelper::substring($sql, 0, strlen($sql) - strlen($this->delimiter) - 1), $out); $sql = ""; } } // Catch any statements not followed by ; if ($sql !== "") { $this->execSQL($sql, $out); } } catch (SQLException $e) { throw new BuildException("Error running statements", $e); } }
/** * <p> * This validates each contained selector * provided that the selector implements the validate interface. * </p> * <p>Ordinarily, this will validate all the elements of a selector * container even if the isSelected() method of some elements is * never called. This has two effects:</p> * <ul> * <li>Validation will often occur twice. * <li>Since it is not required that selectors derive from * BaseSelector, there could be selectors in the container whose * error conditions are not detected if their isSelected() call * is never made. * </ul> */ public function validate() { if ($this->isReference()) { $dataTypeName = StringHelper::substring(get_class(), strrpos(get_class(), '\\') + 1); $this->getCheckedRef(get_class(), $dataTypeName)->validate(); } $selectorElements = $this->selectorElements(); $this->dieOnCircularReference($selectorElements, $this->getProject()); foreach ($selectorElements as $o) { if ($o instanceof BaseSelector) { $o->validate(); } } }