Skip to content

Commit d1dd7a6

Browse files
committed
add dropColumn schema migration feature
1 parent 1f777ab commit d1dd7a6

File tree

4 files changed

+169
-18
lines changed

4 files changed

+169
-18
lines changed

src/DB2Connection.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@
22

33
namespace Cooperl\Database\DB2;
44

5-
use Cooperl\Database\DB2\Query\Processors\DB2ZOSProcessor;
65
use PDO;
76

87
use Illuminate\Database\Connection;
98

109
use Cooperl\Database\DB2\Schema\Builder;
1110
use Cooperl\Database\DB2\Query\Processors\DB2Processor;
11+
use Cooperl\Database\DB2\Query\Processors\DB2ZOSProcessor;
1212
use Cooperl\Database\DB2\Query\Grammars\DB2Grammar as QueryGrammar;
1313
use Cooperl\Database\DB2\Schema\Grammars\DB2Grammar as SchemaGrammar;
14+
use Cooperl\Database\DB2\Schema\Grammars\DB2ExpressCGrammar;
1415

1516
/**
1617
* Class DB2Connection
@@ -67,14 +68,25 @@ public function resetCurrentSchema()
6768
*/
6869
public function setCurrentSchema($schema)
6970
{
70-
//$this->currentSchema = $schema;
7171
$this->statement('SET SCHEMA ?', [strtoupper($schema)]);
7272
}
7373

74+
/**
75+
* Execute a system command on IBMi.
76+
*
77+
* @param $command
78+
*
79+
* @return string
80+
*/
81+
public function executeCommand($command)
82+
{
83+
$this->statement('CALL QSYS2.QCMDEXC(?)', [$command]);
84+
}
85+
7486
/**
7587
* Get a schema builder instance for the connection.
7688
*
77-
* @return \Illuminate\Database\Schema\MySqlBuilder
89+
* @return \Cooperl\Database\DB2\Schema\Builder
7890
*/
7991
public function getSchemaBuilder()
8092
{
@@ -121,7 +133,7 @@ protected function getDefaultSchemaGrammar()
121133
/**
122134
* Get the default post processor instance.
123135
*
124-
* @return \Illuminate\Database\Query\Processors\PostgresProcessor
136+
* @return \Cooperl\Database\DB2\Query\Processors\DB2Processor|\Cooperl\Database\DB2\Query\Processors\DB2ZOSProcessor
125137
*/
126138
protected function getDefaultPostProcessor()
127139
{

src/Query/Grammars/DB2Grammar.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ protected function compileAnsiOffset(Builder $query, $components)
104104
}
105105

106106
$components['columns'] = $this->compileOver($orderings, $columns);
107-
107+
108108
// if there are bindings in the order, we need to move them to the select since we are moving the parameter
109109
// markers there with the OVER statement
110110
if(isset($query->getRawBindings()['order'])){
@@ -198,7 +198,7 @@ public function compileExists(Builder $query)
198198

199199
$existsQuery->columns = [];
200200

201-
return $this->compileSelect($existsQuery->selectRaw('1')->limit(1));
201+
return $this->compileSelect($existsQuery->selectRaw('1 exists')->limit(1));
202202
}
203203

204204
/**

src/Schema/Blueprint.php

Lines changed: 72 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace Cooperl\Database\DB2\Schema;
44

5+
use Illuminate\Database\Connection;
6+
use Illuminate\Database\Schema\Grammars\Grammar;
7+
58
/**
69
* Class Blueprint
710
*
@@ -10,27 +13,62 @@
1013
class Blueprint extends \Illuminate\Database\Schema\Blueprint
1114
{
1215

13-
public function synchro($index, $masterizable = false)
16+
/**
17+
* The sequence number of reply list entries.
18+
*
19+
* @var int
20+
*/
21+
private $replyListSequenceNumber;
22+
23+
/**
24+
* Get the sequence number of reply list entries.
25+
*
26+
* @return int
27+
*/
28+
public function getReplyListSequenceNumber()
1429
{
30+
return $this->replyListSequenceNumber;
31+
}
1532

16-
$this->string('id_sync', 20)
17-
->index($index);
18-
$this->string('hashcode', 32);
33+
/**
34+
* Set the sequence number of reply list entries.
35+
*
36+
* @param int $replyListSequenceNumber
37+
* @return void
38+
*/
39+
public function setReplyListSequenceNumber(int $replyListSequenceNumber)
40+
{
41+
return $this->replyListSequenceNumber = $replyListSequenceNumber;
42+
}
1943

20-
if (true === $masterizable) {
21-
$this->boolean('data_master')
22-
->default(true);
23-
}
44+
/**
45+
* Get the raw SQL statements for the blueprint.
46+
*
47+
* @param \Illuminate\Database\Connection $connection
48+
* @param \Illuminate\Database\Schema\Grammars\Grammar $grammar
49+
* @return array
50+
*/
51+
public function toSql(Connection $connection, Grammar $grammar)
52+
{
53+
$this->addReplyListEntryCommands($connection);
54+
55+
return parent::toSql($connection, $grammar);
2456
}
2557

2658
/**
27-
* @param string $index
59+
* Add the commands that are necessary to DROP and Rename statements on IBMi.
60+
*
61+
* @param \Illuminate\Database\Connection $connection
62+
* @return void
2863
*/
29-
public function dropSynchro($index)
64+
protected function addReplyListEntryCommands(Connection $connection)
3065
{
31-
$this->dropColumn('id_sync', 'hashcode');
32-
$this->dropIndex($index);
66+
if ($this->commandsNamed(['dropColumn', 'renameColumn'])->count() > 0) {
67+
array_unshift($this->commands, $this->createCommand('addReplyListEntry'), $this->createCommand('changeJob'));
68+
array_push($this->commands, $this->createCommand('removeReplyListEntry'));
69+
}
3370
}
71+
3472
/**
3573
* Specify a system name for the table.
3674
*
@@ -124,4 +162,26 @@ public function numeric($column, $total = 8, $places = 2)
124162
{
125163
return $this->addColumn('numeric', $column, compact('total', 'places'));
126164
}
165+
166+
public function synchro($index, $masterizable = false)
167+
{
168+
169+
$this->string('id_sync', 20)
170+
->index($index);
171+
$this->string('hashcode', 32);
172+
173+
if (true === $masterizable) {
174+
$this->boolean('data_master')
175+
->default(true);
176+
}
177+
}
178+
179+
/**
180+
* @param string $index
181+
*/
182+
public function dropSynchro($index)
183+
{
184+
$this->dropColumn('id_sync', 'hashcode');
185+
$this->dropIndex($index);
186+
}
127187
}

src/Schema/Grammars/DB2Grammar.php

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,4 +831,83 @@ protected function getDefaultValue($value)
831831

832832
return "'" . strval($value) . "'";
833833
}
834+
835+
/**
836+
* Compile a executeCommand command.
837+
*
838+
* @param \Illuminate\Database\Schema\Blueprint $blueprint
839+
* @param \Illuminate\Support\Fluent $command
840+
*
841+
* @return string
842+
*/
843+
private function compileExecuteCommand(Blueprint $blueprint, Fluent $command)
844+
{
845+
return "CALL QSYS2.QCMDEXC('" . $command->command . "')";
846+
}
847+
848+
/**
849+
* Compile an addReplyListEntry command.
850+
*
851+
* @param \Illuminate\Database\Schema\Blueprint $blueprint
852+
* @param \Illuminate\Support\Fluent $command
853+
* @param \Illuminate\Database\Connection $connection
854+
*
855+
* @return string
856+
*/
857+
public function compileAddReplyListEntry(Blueprint $blueprint, Fluent $command, Connection $connection)
858+
{
859+
$sequenceNumberQuery = <<<EOT
860+
with reply_list_info(sequence_number) as (
861+
values(1)
862+
union all
863+
select sequence_number + 1
864+
from reply_list_info
865+
where sequence_number + 1 between 2 and 9999
866+
)
867+
select min(sequence_number) sequence_number
868+
from reply_list_info
869+
where not exists (
870+
select 1
871+
from qsys2.reply_list_info rli
872+
where rli.sequence_number = reply_list_info.sequence_number
873+
)
874+
EOT;
875+
876+
$blueprint->setReplyListSequenceNumber($sequenceNumber = $connection->selectOne($sequenceNumberQuery)->sequence_number);
877+
$command->command = "ADDRPYLE SEQNBR($sequenceNumber) MSGID(CPA32B2) RPY(''I'')";
878+
879+
return $this->compileExecuteCommand($blueprint, $command);
880+
}
881+
882+
/**
883+
* Compile a removeReplyListEntry command.
884+
*
885+
* @param \Illuminate\Database\Schema\Blueprint $blueprint
886+
* @param \Illuminate\Support\Fluent $command
887+
*
888+
* @return string
889+
*/
890+
public function compileRemoveReplyListEntry(Blueprint $blueprint, Fluent $command)
891+
{
892+
$sequenceNumber = $blueprint->getReplyListSequenceNumber();
893+
$command->command = "RMVRPYLE SEQNBR($sequenceNumber)";
894+
895+
return $this->compileExecuteCommand($blueprint, $command);
896+
}
897+
898+
/**
899+
* Compile a changeJob command.
900+
*
901+
* @param \Illuminate\Database\Schema\Blueprint $blueprint
902+
* @param \Illuminate\Support\Fluent $command
903+
*
904+
* @return string
905+
*/
906+
public function compileChangeJob(Blueprint $blueprint, Fluent $command)
907+
{
908+
$command->command = 'CHGJOB INQMSGRPY(*SYSRPYL)';
909+
910+
return $this->compileExecuteCommand($blueprint, $command);
911+
}
912+
834913
}

0 commit comments

Comments
 (0)