diff --git a/src/DB2Connection.php b/src/DB2Connection.php index c07b813..fc61f70 100644 --- a/src/DB2Connection.php +++ b/src/DB2Connection.php @@ -2,15 +2,16 @@ namespace Cooperl\Database\DB2; -use Cooperl\Database\DB2\Query\Processors\DB2ZOSProcessor; use PDO; use Illuminate\Database\Connection; use Cooperl\Database\DB2\Schema\Builder; use Cooperl\Database\DB2\Query\Processors\DB2Processor; +use Cooperl\Database\DB2\Query\Processors\DB2ZOSProcessor; use Cooperl\Database\DB2\Query\Grammars\DB2Grammar as QueryGrammar; use Cooperl\Database\DB2\Schema\Grammars\DB2Grammar as SchemaGrammar; +use Cooperl\Database\DB2\Schema\Grammars\DB2ExpressCGrammar; /** * Class DB2Connection @@ -67,14 +68,25 @@ class DB2Connection extends Connection */ public function setCurrentSchema($schema) { - //$this->currentSchema = $schema; $this->statement('SET SCHEMA ?', [strtoupper($schema)]); } + /** + * Execute a system command on IBMi. + * + * @param $command + * + * @return string + */ + public function executeCommand($command) + { + $this->statement('CALL QSYS2.QCMDEXC(?)', [$command]); + } + /** * Get a schema builder instance for the connection. * - * @return \Illuminate\Database\Schema\MySqlBuilder + * @return \Cooperl\Database\DB2\Schema\Builder */ public function getSchemaBuilder() { @@ -121,7 +133,7 @@ class DB2Connection extends Connection /** * Get the default post processor instance. * - * @return \Illuminate\Database\Query\Processors\PostgresProcessor + * @return \Cooperl\Database\DB2\Query\Processors\DB2Processor|\Cooperl\Database\DB2\Query\Processors\DB2ZOSProcessor */ protected function getDefaultPostProcessor() { diff --git a/src/Query/Grammars/DB2Grammar.php b/src/Query/Grammars/DB2Grammar.php index b81c028..1d4efc0 100644 --- a/src/Query/Grammars/DB2Grammar.php +++ b/src/Query/Grammars/DB2Grammar.php @@ -104,7 +104,7 @@ class DB2Grammar extends Grammar } $components['columns'] = $this->compileOver($orderings, $columns); - + // if there are bindings in the order, we need to move them to the select since we are moving the parameter // markers there with the OVER statement if(isset($query->getRawBindings()['order'])){ @@ -198,7 +198,7 @@ class DB2Grammar extends Grammar $existsQuery->columns = []; - return $this->compileSelect($existsQuery->selectRaw('1')->limit(1)); + return $this->compileSelect($existsQuery->selectRaw('1 exists')->limit(1)); } /** diff --git a/src/Schema/Blueprint.php b/src/Schema/Blueprint.php index d489952..6aedfea 100644 --- a/src/Schema/Blueprint.php +++ b/src/Schema/Blueprint.php @@ -2,6 +2,9 @@ namespace Cooperl\Database\DB2\Schema; +use Illuminate\Database\Connection; +use Illuminate\Database\Schema\Grammars\Grammar; + /** * Class Blueprint * @@ -10,27 +13,62 @@ namespace Cooperl\Database\DB2\Schema; class Blueprint extends \Illuminate\Database\Schema\Blueprint { - public function synchro($index, $masterizable = false) + /** + * The sequence number of reply list entries. + * + * @var int + */ + private $replyListSequenceNumber; + + /** + * Get the sequence number of reply list entries. + * + * @return int + */ + public function getReplyListSequenceNumber() { - - $this->string('id_sync', 20) - ->index($index); - $this->string('hashcode', 32); - - if (true === $masterizable) { - $this->boolean('data_master') - ->default(true); - } + return $this->replyListSequenceNumber; } /** - * @param string $index + * Set the sequence number of reply list entries. + * + * @param int $replyListSequenceNumber + * @return void */ - public function dropSynchro($index) + public function setReplyListSequenceNumber(int $replyListSequenceNumber) { - $this->dropColumn('id_sync', 'hashcode'); - $this->dropIndex($index); + return $this->replyListSequenceNumber = $replyListSequenceNumber; } + + /** + * Get the raw SQL statements for the blueprint. + * + * @param \Illuminate\Database\Connection $connection + * @param \Illuminate\Database\Schema\Grammars\Grammar $grammar + * @return array + */ + public function toSql(Connection $connection, Grammar $grammar) + { + $this->addReplyListEntryCommands($connection); + + return parent::toSql($connection, $grammar); + } + + /** + * Add the commands that are necessary to DROP and Rename statements on IBMi. + * + * @param \Illuminate\Database\Connection $connection + * @return void + */ + protected function addReplyListEntryCommands(Connection $connection) + { + if ($this->commandsNamed(['dropColumn', 'renameColumn'])->count() > 0) { + array_unshift($this->commands, $this->createCommand('addReplyListEntry'), $this->createCommand('changeJob')); + array_push($this->commands, $this->createCommand('removeReplyListEntry')); + } + } + /** * Specify a system name for the table. * @@ -124,4 +162,26 @@ class Blueprint extends \Illuminate\Database\Schema\Blueprint { return $this->addColumn('numeric', $column, compact('total', 'places')); } + + public function synchro($index, $masterizable = false) + { + + $this->string('id_sync', 20) + ->index($index); + $this->string('hashcode', 32); + + if (true === $masterizable) { + $this->boolean('data_master') + ->default(true); + } + } + + /** + * @param string $index + */ + public function dropSynchro($index) + { + $this->dropColumn('id_sync', 'hashcode'); + $this->dropIndex($index); + } } diff --git a/src/Schema/Grammars/DB2Grammar.php b/src/Schema/Grammars/DB2Grammar.php index d1c9764..3138e64 100644 --- a/src/Schema/Grammars/DB2Grammar.php +++ b/src/Schema/Grammars/DB2Grammar.php @@ -831,4 +831,83 @@ class DB2Grammar extends Grammar return "'" . strval($value) . "'"; } + + /** + * Compile a executeCommand command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * + * @return string + */ + private function compileExecuteCommand(Blueprint $blueprint, Fluent $command) + { + return "CALL QSYS2.QCMDEXC('" . $command->command . "')"; + } + + /** + * Compile an addReplyListEntry command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @param \Illuminate\Database\Connection $connection + * + * @return string + */ + public function compileAddReplyListEntry(Blueprint $blueprint, Fluent $command, Connection $connection) + { + $sequenceNumberQuery = <<setReplyListSequenceNumber($sequenceNumber = $connection->selectOne($sequenceNumberQuery)->sequence_number); + $command->command = "ADDRPYLE SEQNBR($sequenceNumber) MSGID(CPA32B2) RPY(''I'')"; + + return $this->compileExecuteCommand($blueprint, $command); + } + + /** + * Compile a removeReplyListEntry command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * + * @return string + */ + public function compileRemoveReplyListEntry(Blueprint $blueprint, Fluent $command) + { + $sequenceNumber = $blueprint->getReplyListSequenceNumber(); + $command->command = "RMVRPYLE SEQNBR($sequenceNumber)"; + + return $this->compileExecuteCommand($blueprint, $command); + } + + /** + * Compile a changeJob command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * + * @return string + */ + public function compileChangeJob(Blueprint $blueprint, Fluent $command) + { + $command->command = 'CHGJOB INQMSGRPY(*SYSRPYL)'; + + return $this->compileExecuteCommand($blueprint, $command); + } + }