123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593 |
- <?php
- require_once 'phing/tasks/ext/creole/CreoleTask.php';
- include_once 'phing/system/io/StringReader.php';
- class CreoleSQLExecTask extends CreoleTask {
- private $goodSql = 0;
- private $totalSql = 0;
- const DELIM_ROW = "row";
- const DELIM_NORMAL = "normal";
-
- private $conn = null;
-
- private $filesets = array();
-
- private $filterChains = array();
-
- private $statement = null;
-
- private $srcFile = null;
-
- private $sqlCommand = "";
-
- private $transactions = array();
-
- private $delimiter = ";";
-
-
- private $delimiterType = "normal";
-
-
- private $print = false;
-
- private $showheaders = true;
-
- private $output = null;
-
-
- private $onError = "abort";
-
-
- private $encoding = null;
-
- private $append = false;
-
-
- public function setSrc(PhingFile $srcFile) {
- $this->srcFile = $srcFile;
- }
-
-
- public function addText($sql) {
- $this->sqlCommand .= $sql;
- }
-
-
- public function addFileset(FileSet $set) {
- $this->filesets[] = $set;
- }
-
- function createFilterChain() {
- $num = array_push($this->filterChains, new FilterChain($this->project));
- return $this->filterChains[$num-1];
- }
-
- public function createTransaction() {
- $t = new SQLExecTransaction($this);
- $this->transactions[] = $t;
- return $t;
- }
-
-
- public function setEncoding($encoding) {
- $this->encoding = $encoding;
- }
-
-
- public function setDelimiter($delimiter)
- {
- $this->delimiter = $delimiter;
- }
-
- public function setDelimiterType($delimiterType)
- {
- $this->delimiterType = $delimiterType;
- }
-
-
- public function setPrint($print)
- {
- $this->print = (boolean) $print;
- }
-
-
- public function setShowheaders($showheaders) {
- $this->showheaders = (boolean) $showheaders;
- }
-
- public function setOutput(PhingFile $output) {
- $this->output = $output;
- }
-
- public function setAppend($append) {
- $this->append = (boolean) $append;
- }
-
-
- public function setOnerror($action) {
- $this->onError = $action;
- }
-
- public function main() {
-
- $savedTransaction = array();
- for($i=0,$size=count($this->transactions); $i < $size; $i++) {
- $savedTransaction[] = clone $this->transactions[$i];
- }
-
- $savedSqlCommand = $this->sqlCommand;
- $this->sqlCommand = trim($this->sqlCommand);
- try {
- if ($this->srcFile === null && $this->sqlCommand === ""
- && empty($this->filesets)) {
- if (count($this->transactions) === 0) {
- throw new BuildException("Source file or fileset, "
- . "transactions or sql statement "
- . "must be set!", $this->location);
- }
- }
-
- if ($this->srcFile !== null && !$this->srcFile->exists()) {
- throw new BuildException("Source file does not exist!", $this->location);
- }
-
- for ($i = 0,$size=count($this->filesets); $i < $size; $i++) {
- $fs = $this->filesets[$i];
- $ds = $fs->getDirectoryScanner($this->project);
- $srcDir = $fs->getDir($this->project);
-
- $srcFiles = $ds->getIncludedFiles();
-
-
- for ($j=0, $size=count($srcFiles); $j < $size; $j++) {
- $t = $this->createTransaction();
- $t->setSrc(new PhingFile($srcDir, $srcFiles[$j]));
- }
- }
-
-
- $t = $this->createTransaction();
- if ($this->srcFile) $t->setSrc($this->srcFile);
- $t->addText($this->sqlCommand);
- $this->conn = $this->getConnection();
- try {
-
- $this->statement = $this->conn->createStatement();
-
- $out = null;
-
- try {
-
- if ($this->output !== null) {
- $this->log("Opening output file " . $this->output, Project::MSG_VERBOSE);
- $out = new BufferedWriter(new FileWriter($this->output->getAbsolutePath(), $this->append));
- }
-
-
- for ($i=0,$size=count($this->transactions); $i < $size; $i++) {
- $this->transactions[$i]->runTransaction($out);
- if (!$this->isAutocommit()) {
- $this->log("Commiting transaction", Project::MSG_VERBOSE);
- $this->conn->commit();
- }
- }
- if ($out) $out->close();
- } catch (Exception $e) {
- if ($out) $out->close();
- throw $e;
- }
- } catch (IOException $e) {
- if (!$this->isAutocommit() && $this->conn !== null && $this->onError == "abort") {
- try {
- $this->conn->rollback();
- } catch (SQLException $ex) {}
- }
- throw new BuildException($e->getMessage(), $this->location);
- } catch (SQLException $e){
- if (!$this->isAutocommit() && $this->conn !== null && $this->onError == "abort") {
- try {
- $this->conn->rollback();
- } catch (SQLException $ex) {}
- }
- throw new BuildException($e->getMessage(), $this->location);
- }
-
- $this->log($this->goodSql . " of " . $this->totalSql .
- " SQL statements executed successfully");
- } catch (Exception $e) {
- $this->transactions = $savedTransaction;
- $this->sqlCommand = $savedSqlCommand;
- throw $e;
- }
-
- $this->transactions = $savedTransaction;
- $this->sqlCommand = $savedSqlCommand;
-
- }
-
- 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())) {
- $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);
-
-
-
- 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 = "";
- }
- }
-
- if ($sql !== "") {
- $this->execSQL($sql, $out);
- }
- } catch (SQLException $e) {
- throw new BuildException("Error running statements", $e);
- }
- }
-
-
-
- protected function execSQL($sql, $out = null) {
-
- if (trim($sql) == "") {
- return;
- }
- try {
- $this->totalSql++;
- if (!$this->statement->execute($sql)) {
- $this->log($this->statement->getUpdateCount() . " rows affected", Project::MSG_VERBOSE);
- } else {
- if ($this->print) {
- $this->printResults($out);
- }
- }
-
- $this->goodSql++;
-
- } catch (SQLException $e) {
- $this->log("Failed to execute: " . $sql, Project::MSG_ERR);
- if ($this->onError != "continue") {
- throw new BuildException("Failed to execute SQL", $e);
- }
- $this->log($e->getMessage(), Project::MSG_ERR);
- }
- }
-
-
- protected function printResults($out = null) {
-
- $rs = null;
- do {
- $rs = $this->statement->getResultSet();
-
- if ($rs !== null) {
-
- $this->log("Processing new result set.", Project::MSG_VERBOSE);
-
- $line = "";
- $colsprinted = false;
-
- while ($rs->next()) {
- $fields = $rs->getRow();
-
- if (!$colsprinted && $this->showheaders) {
- $first = true;
- foreach($fields as $fieldName => $ignore) {
- if ($first) $first = false; else $line .= ",";
- $line .= $fieldName;
- }
- if ($out !== null) {
- $out->write($line);
- $out->newLine();
- } else {
- print($line.PHP_EOL);
- }
- $line = "";
- $colsprinted = true;
- }
-
- $first = true;
- foreach($fields as $columnValue) {
-
- if ($columnValue != null) {
- $columnValue = trim($columnValue);
- }
- if ($first) {
- $first = false;
- } else {
- $line .= ",";
- }
- $line .= $columnValue;
- }
-
- if ($out !== null) {
- $out->write($line);
- $out->newLine();
- } else {
- print($line . PHP_EOL);
- }
- $line = "";
-
- }
- }
- } while ($this->statement->getMoreResults());
- print(PHP_EOL);
- if ($out !== null) $out->newLine();
- }
- }
- class SQLExecTransaction {
- private $tSrcFile = null;
- private $tSqlCommand = "";
- private $parent;
-
- function __construct($parent)
- {
-
- $this->parent = $parent;
- }
-
- public function setSrc(PhingFile $src)
- {
- $this->tSrcFile = $src;
- }
- public function addText($sql)
- {
- $this->tSqlCommand .= $sql;
- }
-
- public function runTransaction($out = null)
- {
- if (!empty($this->tSqlCommand)) {
- $this->parent->log("Executing commands", Project::MSG_INFO);
- $this->parent->runStatements(new StringReader($this->tSqlCommand), $out);
- }
- if ($this->tSrcFile !== null) {
- $this->parent->log("Executing file: " . $this->tSrcFile->getAbsolutePath(),
- Project::MSG_INFO);
- $reader = new FileReader($this->tSrcFile);
- $this->parent->runStatements($reader, $out);
- $reader->close();
- }
- }
- }
|