1 <?php
2
3 4 5 6 7 8 9 10 11
12 class rex_sql_schema_dumper
13 {
14 15 16 17 18 19 20
21 public function dumpTable(rex_sql_table $table)
22 {
23 $code = 'rex_sql_table::get('.$this->tableName($table->getName()).')';
24
25 $setPrimaryKey = true;
26 $primaryKeyIsId = ['id'] === $table->getPrimaryKey();
27 $idColumn = new rex_sql_column('id', 'int(10) unsigned', false, null, 'auto_increment');
28
29 foreach ($table->getColumns() as $column) {
30 if ($primaryKeyIsId && $column->equals($idColumn)) {
31 $code .= "\n ->ensurePrimaryIdColumn()";
32 $setPrimaryKey = false;
33
34 continue;
35 }
36
37 $code .= "\n ->ensureColumn(".$this->getColumn($column).')';
38 }
39
40 if ($setPrimaryKey && $table->getPrimaryKey()) {
41 $code .= "\n ->setPrimaryKey(".$this->getPrimaryKey($table->getPrimaryKey()).')';
42 }
43
44 foreach ($table->getIndexes() as $index) {
45 $code .= "\n ->ensureIndex(".$this->getIndex($index).')';
46 }
47
48 foreach ($table->getForeignKeys() as $foreignKey) {
49 $code .= "\n ->ensureForeignKey(".$this->getForeignKey($foreignKey).')';
50 }
51
52 $code .= "\n ->ensure();\n";
53
54 return $code;
55 }
56
57 private function getColumn(rex_sql_column $column)
58 {
59 $parameters = [];
60 $nonDefault = false;
61
62 if (null !== $column->getExtra()) {
63 $parameters[] = $this->scalar($column->getExtra());
64 $nonDefault = true;
65 }
66
67 if ($nonDefault || null !== $column->getDefault()) {
68 $parameters[] = $this->scalar($column->getDefault());
69 $nonDefault = true;
70 }
71
72 if ($nonDefault || false !== $column->isNullable()) {
73 $parameters[] = $this->scalar($column->isNullable());
74 }
75
76 $parameters[] = $this->scalar($column->getType());
77 $parameters[] = $this->scalar($column->getName());
78
79 return 'new rex_sql_column('.implode(', ', array_reverse($parameters)).')';
80 }
81
82 private function getIndex(rex_sql_index $index)
83 {
84 $parameters = [
85 $this->scalar($index->getName()),
86 $this->simpleArray($index->getColumns()),
87 ];
88
89 static $types = [
90 rex_sql_index::UNIQUE => 'rex_sql_index::UNIQUE',
91 rex_sql_index::FULLTEXT => 'rex_sql_index::FULLTEXT',
92 ];
93
94 if (rex_sql_index::INDEX !== $index->getType()) {
95 $parameters[] = $types[$index->getType()];
96 }
97
98 return 'new rex_sql_index('.implode(', ', $parameters).')';
99 }
100
101 private function getForeignKey(rex_sql_foreign_key $foreignKey)
102 {
103 $parameters = [
104 $this->scalar($foreignKey->getName()),
105 $this->tableName($foreignKey->getTable()),
106 $this->map($foreignKey->getColumns()),
107 ];
108
109 static $options = [
110 rex_sql_foreign_key::RESTRICT => 'rex_sql_foreign_key::RESTRICT',
111 rex_sql_foreign_key::CASCADE => 'rex_sql_foreign_key::CASCADE',
112 rex_sql_foreign_key::SET_NULL => 'rex_sql_foreign_key::SET_NULL',
113 ];
114
115 $nonDefaultOnDelete = rex_sql_foreign_key::RESTRICT !== $foreignKey->getOnDelete();
116
117 if ($nonDefaultOnDelete || rex_sql_foreign_key::RESTRICT !== $foreignKey->getOnUpdate()) {
118 $parameters[] = $options[$foreignKey->getOnUpdate()];
119 }
120
121 if ($nonDefaultOnDelete) {
122 $parameters[] = $options[$foreignKey->getOnDelete()];
123 }
124
125 return 'new rex_sql_foreign_key('.implode(', ', $parameters).')';
126 }
127
128 private function getPrimaryKey(array $primaryKey)
129 {
130 if (1 === count($primaryKey)) {
131 return $this->scalar(reset($primaryKey));
132 }
133
134 return $this->simpleArray($primaryKey);
135 }
136
137 private function tableName($name)
138 {
139 if (0 !== strpos($name, rex::getTablePrefix())) {
140 return $this->scalar($name);
141 }
142
143 $name = substr($name, strlen(rex::getTablePrefix()));
144
145 return 'rex::getTable('.$this->scalar($name).')';
146 }
147
148 private function scalar($scalar)
149 {
150 if (null === $scalar) {
151 return 'null';
152 }
153
154 return var_export($scalar, true);
155 }
156
157 private function simpleArray(array $list)
158 {
159 $parts = [];
160
161 foreach ($list as $value) {
162 $parts[] = $this->scalar($value);
163 }
164
165 return '['.implode(', ', $parts).']';
166 }
167
168 private function map(array $map)
169 {
170 $parts = [];
171
172 foreach ($map as $key => $value) {
173 $parts[] = $this->scalar($key).' => '.$this->scalar($value);
174 }
175
176 return '['.implode(', ', $parts).']';
177 }
178 }
179