14 require(dirname(dirname(dirname(dirname(__FILE__)))) .
'/tools/bootstrap.inc.php');
31 $this->source = array_shift(
$argv);
32 $this->className = array_shift(
$argv);
35 if (empty($this->source) || !file_exists($this->source)) {
40 if (empty($this->className) | !preg_match(
'/^[a-zA-Z]+$/', $this->className)) {
50 echo
"Script to convert ADODB XMLSchema-based schema descriptors to Illuminate migrations\n\n"
51 .
"Usage: {$this->scriptName} input-schema-file.xml GenerateClassNamed\n\n";
58 $doc =
new DOMDocument();
59 $doc->preserveWhiteSpace =
false;
60 $doc->loadXML(file_get_contents($this->source));
61 if ($doc->documentElement->nodeName !=
'schema')
throw new Exception(
'Invalid document element ' . $this->documentElement->nodeName);
76 use Illuminate\Database\Migrations\Migration;
77 use Illuminate\Database\Schema\Builder;
78 use Illuminate\Database\Schema\Blueprint;
79 use Illuminate\Database\Capsule\Manager as Capsule;
81 class $this->className extends Migration {
86 public function up() {\n";
87 foreach ($doc->documentElement->childNodes as $tableNode) {
88 if ($tableNode->nodeType == XML_COMMENT_NODE)
continue;
89 if ($tableNode->nodeName !=
'table')
throw new Exception(
'Unexpected table node name ' . $tableNode->nodeName);
90 foreach ($tableNode->childNodes as $tableChild) {
91 if ($tableChild->nodeName ==
'descr') echo
"\t\t// " . $tableChild->nodeValue .
"\n";
93 echo
"\t\tCapsule::schema()->create('" . $tableNode->getAttribute(
'name') .
"', function (Blueprint \$table) {\n";
95 $hasAutoIncrementNamed =
null;
96 foreach ($tableNode->childNodes as $tableChild)
switch (
true) {
97 case $tableChild->nodeType == XML_COMMENT_NODE:
throw new Exception(
'Unexpected comment in table ' . $tableNode->getAttribute(
'name') .
'!');
98 case $tableChild->nodeName ==
'field':
100 foreach ($tableChild->childNodes as $fieldChild)
switch (
true) {
101 case $fieldChild->nodeType == XML_COMMENT_NODE:
102 echo
"\t\t\t// " . $fieldChild->nodeValue .
"\n";
106 $allowDefault =
true;
107 switch ($tableChild->getAttribute(
'type')) {
109 echo
"\$table->longText('" . $tableChild->getAttribute(
'name') .
"')";
110 $allowDefault =
false;
113 echo
"\$table->text('" . $tableChild->getAttribute(
'name') .
"')";
114 $allowDefault =
false;
120 echo
"\$table->tinyInteger('" . $tableChild->getAttribute(
'name') .
"')";
123 echo
"\$table->smallInteger('" . $tableChild->getAttribute(
'name') .
"')";
126 echo
"\$table->integer('" . $tableChild->getAttribute(
'name') .
"')";
129 echo
"\$table->bigInteger('" . $tableChild->getAttribute(
'name') .
"')";
132 echo
"\$table->float('" . $tableChild->getAttribute(
'name') .
"', 8, 2)";
135 echo
"\$table->datetime('" . $tableChild->getAttribute(
'name') .
"')";
138 echo
"\$table->date('" . $tableChild->getAttribute(
'name') .
"')";
141 echo
"\$table->string('" . $tableChild->getAttribute(
'name') .
"', " . (int) $tableChild->getAttribute(
'size') .
")";
144 echo
"\$table->string('" . $tableChild->getAttribute(
'name') .
"', " . (int) $tableChild->getAttribute(
'size') .
")";
146 default:
throw new Exception(
'Unspecified or unknown table type ' . $tableChild->getAttribute(
'type') .
' in column ' . $tableChild->getAttribute(
'name') .
' of table ' . $tableNode->getAttribute(
'name'));
149 $autoIncrement =
false;
150 foreach ($tableChild->childNodes as $fieldChild)
switch (
true) {
151 case $fieldChild->nodeType == XML_COMMENT_NODE:
break;
152 case $fieldChild->nodeName ==
'NOTNULL': $nullable =
false;
break;
153 case $fieldChild->nodeName ==
'AUTOINCREMENT':
154 $autoIncrement =
true;
155 $hasAutoIncrementNamed = $tableChild->getAttribute(
'name');
158 case $fieldChild->nodeName ==
'KEY': $keys[] = $tableChild->getAttribute(
'name');
break;
159 case $fieldChild->nodeName ==
'DEFAULT':
161 $value = $fieldChild->getAttribute(
'VALUE');
162 if (is_string($value) && ctype_digit($value)) $value = (int) $value;
163 echo
"->default(" . var_export($value,
true) .
")";
166 case $fieldChild->nodeName ==
'descr': echo
"->comment(" . var_export($fieldChild->nodeValue,
true) .
")";
break;
167 case $fieldChild->nodeType == XML_TEXT_NODE:
168 if (trim($fieldChild->nodeValue) !==
'')
throw new Exception(
'Unexpected content in field node!');
170 default:
throw new Exception(
'Unhandled child node (type ' . $fieldChild->nodeType .
') to column ' . $tableChild->getAttribute(
'name') .
' of table ' . $tableNode->getAttribute(
'name'));
172 if ($autoIncrement) echo
"->autoIncrement()";
173 if ($nullable && !in_array($tableChild->getAttribute(
'name'), $keys)) echo
"->nullable()";
176 case $tableChild->nodeName ==
'index':
177 if (!$tableChild->hasAttribute(
'name'))
throw new Exception(
'Unnamed index on table ' . $tableNode->getAttribute(
'name'));
178 $indexType =
'index';
180 foreach ($tableChild->childNodes as $indexChild)
switch (
true) {
181 case $indexChild->nodeType == XML_COMMENT_NODE:
182 echo
"\t\t\t// " . $indexChild->nodeValue .
"\n";
184 case $indexChild->nodeName ==
'UNIQUE': $indexType =
'unique';
break;
185 case $indexChild->nodeName ==
'col': $columns[] = trim($indexChild->nodeValue);
187 default:
throw new Exception(
'Unhandled index node child ' . $indexChild->nodeName);
189 if (empty($columns))
throw new Exception(
'Empty column list for index on table ' . $tableNode->getAttribute(
'name') .
'))!');
190 echo
"\t\t\t\$table->$indexType(['" . implode(
"', '", $columns) .
"'], '" . $tableChild->getAttribute(
'name') .
"');\n";
192 case $tableChild->nodeName ==
'descr':
break;
194 default:
throw new Exception(
'Don\'t know how to handle this table child node (' . $tableChild->nodeName .
'))!');
197 if (count($keys)>1 && $hasAutoIncrementNamed !==
null) {
198 echo
"\t\t// Work-around for compound primary key\n";
199 echo
"\t\tswitch (Capsule::connection()->getDriverName()) {\n";
200 echo
"\t\t\tcase 'mysql': Capsule::connection()->unprepared(\"ALTER TABLE " . $tableNode->getAttribute(
'name') .
" DROP PRIMARY KEY, ADD PRIMARY KEY (" . implode(
", ", $keys) .
")\"); break;\n";
201 echo
"\t\t\tcase 'pgsql': Capsule::connection()->unprepared(\"ALTER TABLE " . $tableNode->getAttribute(
'name') .
" DROP CONSTRAINT " . $tableNode->getAttribute(
'name') .
"_pkey; ALTER TABLE " . $tableNode->getAttribute(
'name') .
" ADD PRIMARY KEY (" . implode(
", ", $keys) .
");\"); break;\n";
203 } elseif (count($keys)==1 && $hasAutoIncrementNamed !==
null) {
205 } elseif ($hasAutoIncrementNamed ===
null) {
207 } elseif (count($keys)==0) {
210 throw new Exception(
'Not sure how to handle primary key setup for table ' . $tableNode->getAttribute(
'name') .
'.');