Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
schema.php
1<?php
2namespace Bitrix\Perfmon\Sql;
3
5
6//Sample usage:
7/*
8\Bitrix\Main\Loader::includeModule('perfmon');
9$dir = new \Bitrix\Main\IO\Directory("/opt/php03.cp1251.www/mercurial/bitrix/modules");
10foreach ($dir->getChildren() as $child)
11{
12 if ($child->isDirectory() && $child->getName()!=='xxx')
13 {
14 echo $child->getName(),": ";
15
16 foreach (array("mysql"=>";", "mssql"=>"GO", "oracle"=>"/") as $db=>$delimiter)
17 {
18 $path = $child->getPath()."/install/db/$db/install.sql";
19 if (!\Bitrix\Main\IO\File::isFileExists($path))
20 $path = $child->getPath()."/install/$db/install.sql";
21 if (!\Bitrix\Main\IO\File::isFileExists($path))
22 continue;
23 //echo "<br>$path<br>";
24 $sql = \Bitrix\Main\IO\File::getFileContents($path);
25 $s = new \Bitrix\Perfmon\Sql\Schema;
26 $s->createFromString($sql, $delimiter);
27 // p r i n t _ r ($s->tables);
28 echo count($s->tables->getList())," ";
29 }
30 echo "\n";
31 }
32}
33*/
34class Schema
35{
37 public $tables = null;
39 public $procedures = null;
41 public $sequences = null;
42
43 public function __construct()
44 {
45 $this->tables = new Collection;
46 $this->procedures = new Collection;
47 $this->sequences = new Collection;
48 }
49
59 public function createFromString($str, $delimiter)
60 {
61 $tokenizer = Tokenizer::createFromString($str);
62 foreach ($this->splitStatements($tokenizer, $delimiter) as $statement)
63 {
64 $this->executeStatement($statement);
65 }
66 }
67
76 protected function splitStatements(Tokenizer $tokenizer, $delimiter = ';')
77 {
78 $result = [];
79 $index = 0;
80 $result[$index] = [];
81
83 $prevToken = null;
85 foreach ($tokenizer->getTokens() as $token)
86 {
87 if (
88 $token->text === $delimiter
89 && $prevToken
90 && mb_strpos($prevToken->text, "\n") !== false
91 )
92 {
93 $index++;
94 $result[$index] = [];
95 }
96 elseif (
97 mb_strpos($token->text, "\n") !== false
98 && $prevToken
99 && $prevToken->text === $delimiter
100 )
101 {
102 array_pop($result[$index]);
103 $index++;
104 $result[$index] = [];
105 }
106 else
107 {
108 $result[$index][] = $token;
109 }
110 $prevToken = $token;
111 }
112
113 foreach ($result as $i => $tokens)
114 {
115 $result[$i] = Tokenizer::createFromTokens($tokens);
116 }
117
118 return $result;
119 }
120
129 protected function executeStatement(Tokenizer $tokenizer)
130 {
132 $tokenizer->resetState();
133 $tokenizer->skipWhiteSpace();
134 if ($tokenizer->testUpperText('CREATE'))
135 {
136 $this->executeCreate($tokenizer);
137 }
138 elseif ($tokenizer->testUpperText('INSERT'))
139 {
140 //skip insert into
141 }
142 elseif ($tokenizer->testUpperText('SET'))
143 {
144 //skip set identity_insert
145 }
146 elseif ($tokenizer->testUpperText('ALTER'))
147 {
148 $this->executeAlter($tokenizer);
149 }
150 elseif ($tokenizer->testUpperText('IF'))
151 {
152 $tokenizer->skipWhiteSpace();
153 if ($tokenizer->testUpperText('OBJECT_ID'))
154 {
155 while (!$tokenizer->endOfInput())
156 {
157 if ($tokenizer->nextToken()->upper === 'CREATE')
158 {
159 break;
160 }
161 }
162 $tokenizer->nextToken();
163 $tokenizer->skipWhiteSpace();
164 if ($tokenizer->testUpperText('TABLE'))
165 {
166 $this->executeCreateTable($tokenizer);
167 }
168 else
169 {
170 throw new NotSupportedException("'CREATE TABLE' expected. line:" . $tokenizer->getCurrentToken()->line);
171 }
172 }
173 elseif ($tokenizer->testUpperText('NOT'))
174 {
175 $tokenizer->skipWhiteSpace();
176 if ($tokenizer->testUpperText('EXISTS'))
177 {
178 while (!$tokenizer->endOfInput())
179 {
180 if ($tokenizer->nextToken()->upper === 'CREATE')
181 {
182 break;
183 }
184 }
185 $tokenizer->nextToken();
186 $tokenizer->skipWhiteSpace();
187
188 if ($tokenizer->testUpperText('UNIQUE'))
189 {
190 $unique = true;
191 $tokenizer->skipWhiteSpace();
192 }
193 else
194 {
195 $unique = false;
196 }
197
198 if ($tokenizer->testUpperText('INDEX'))
199 {
200 $this->executeCreateIndex($tokenizer, $unique);
201 }
202 else
203 {
204 throw new NotSupportedException("'CREATE INDEX' expected. line:" . $tokenizer->getCurrentToken()->line);
205 }
206 }
207 else
208 {
209 throw new NotSupportedException("'NOT EXISTS' expected. line:" . $tokenizer->getCurrentToken()->line);
210 }
211 }
212 else
213 {
214 throw new NotSupportedException("'OBJECT_ID' expected. line:" . $tokenizer->getCurrentToken()->line);
215 }
216 }
217 elseif (!$tokenizer->endOfInput())
218 {
219 throw new NotSupportedException("'CREATE' expected. line:" . $tokenizer->getCurrentToken()->line);
220 }
221 }
222
229 protected function executeCreate(Tokenizer $tokenizer)
230 {
231 $tokenizer->skipWhiteSpace();
232 if ($tokenizer->testUpperText('OR'))
233 {
234 $tokenizer->skipWhiteSpace();
235 if ($tokenizer->testUpperText('REPLACE'))
236 {
237 $tokenizer->skipWhiteSpace();
238 }
239 else
240 {
241 throw new NotSupportedException("'OR REPLACE' expected. line:" . $tokenizer->getCurrentToken()->line);
242 }
243 }
244
245 if ($tokenizer->testUpperText('TABLE'))
246 {
247 $this->executeCreateTable($tokenizer);
248 }
249 elseif ($tokenizer->testUpperText('INDEX'))
250 {
251 $this->executeCreateIndex($tokenizer, false);
252 }
253 elseif ($tokenizer->testUpperText('UNIQUE'))
254 {
255 $tokenizer->skipWhiteSpace();
256 if ($tokenizer->testUpperText('INDEX'))
257 {
258 $tokenizer->skipWhiteSpace();
259 }
260
261 $this->executeCreateIndex($tokenizer, true);
262 }
263 elseif ($tokenizer->testUpperText('FULLTEXT'))
264 {
265 $tokenizer->skipWhiteSpace();
266 if ($tokenizer->testUpperText('INDEX'))
267 {
268 $tokenizer->skipWhiteSpace();
269 }
270
271 $this->executeCreateIndex($tokenizer, false, true);
272 }
273 elseif ($tokenizer->testUpperText('TRIGGER'))
274 {
275 $this->executeCreateTrigger($tokenizer);
276 }
277 elseif (
278 $tokenizer->testUpperText('PROCEDURE')
279 || $tokenizer->testUpperText('FUNCTION')
280 || $tokenizer->testUpperText('TYPE')
281 )
282 {
283 $this->executeCreateProcedure($tokenizer);
284 }
285 elseif ($tokenizer->testUpperText('SEQUENCE'))
286 {
287 $this->executeCreateSequence($tokenizer);
288 }
289 else
290 {
291 throw new NotSupportedException('TABLE|INDEX|UNIQUE|TRIGGER|PROCEDURE|FUNCTION|TYPE|SEQUENCE expected. line:' . $tokenizer->getCurrentToken()->line);
292 }
293 }
294
301 protected function executeAlter(Tokenizer $tokenizer)
302 {
303 $tokenizer->skipWhiteSpace();
304 if ($tokenizer->testUpperText('TABLE'))
305 {
306 $tokenizer->skipWhiteSpace();
307 $tableName = $tokenizer->getCurrentToken()->text;
309 $table = $this->tables->search($tableName);
310 if (!$table)
311 {
312 throw new NotSupportedException("Table [${tableName}] not found. line: " . $tokenizer->getCurrentToken()->line);
313 }
314 $tokenizer->nextToken();
315 $tokenizer->skipWhiteSpace();
316 if ($tokenizer->testUpperText('ADD'))
317 {
318 $tokenizer->skipWhiteSpace();
319 if ($tokenizer->testUpperText('CONSTRAINT'))
320 {
321 $tokenizer->skipWhiteSpace();
322 $table->createConstraint($tokenizer);
323 }
324 }
325 elseif ($tokenizer->testUpperText('MODIFY'))
326 {
327 $tokenizer->skipWhiteSpace();
328 $table->modifyColumn($tokenizer);
329 }
330 elseif ($tokenizer->testUpperText('NOCHECK') || $tokenizer->testUpperText('CHECK'))
331 {
332 //(NOCHECK|CHECK) CONSTRAINT ALL
333 }
334 elseif ($tokenizer->testUpperText('DISABLE') || $tokenizer->testUpperText('ENABLE'))
335 {
336 //(DISABLE|ENABLE) TRIGGER ALL
337 }
338 else
339 {
340 throw new NotSupportedException("'ADD' expected. line:" . $tokenizer->getCurrentToken()->line);
341 }
342 }
343 else
344 {
345 throw new NotSupportedException("'TABLE' expected. line:" . $tokenizer->getCurrentToken()->line);
346 }
347 }
348
355 protected function executeCreateTable(Tokenizer $tokenizer)
356 {
357 $tokenizer->skipWhiteSpace();
358 $this->tables->add(Table::create($tokenizer));
359 }
360
369 protected function executeCreateIndex(Tokenizer $tokenizer, $unique, $fulltext = false)
370 {
371 $tokenizer->skipWhiteSpace();
372
373 $tokenizer->setBookmark();
374
375 Index::searchTableName($tokenizer);
376 $tableName = $tokenizer->getCurrentToken()->text;
377
379 $table = $this->tables->search($tableName);
380 if (!$table)
381 {
382 $table = new Table($tableName);
383 $this->tables->add($table);
384 }
385
386 $tokenizer->restoreBookmark();
387
388 $table->createIndex($tokenizer, $unique, $fulltext);
389 }
390
397 protected function executeCreateTrigger(Tokenizer $tokenizer)
398 {
399 $tokenizer->skipWhiteSpace();
400
401 $tokenizer->setBookmark();
402
403 Trigger::searchTableName($tokenizer);
404 $tableName = $tokenizer->getCurrentToken()->text;
405
407 $table = $this->tables->search($tableName);
408 if (!$table)
409 {
410 throw new NotSupportedException("Table [${tableName}] not found. line: " . $tokenizer->getCurrentToken()->line);
411 }
412
413 $tokenizer->restoreBookmark();
414
415 $table->createTrigger($tokenizer);
416 }
417
424 protected function executeCreateProcedure(Tokenizer $tokenizer)
425 {
426 $tokenizer->putBack();
427 $this->procedures->add(Procedure::create($tokenizer));
428 }
429
436 protected function executeCreateSequence(Tokenizer $tokenizer)
437 {
438 $tokenizer->skipWhiteSpace();
439 $this->sequences->add(Sequence::create($tokenizer));
440 }
441}
static searchTableName(Tokenizer $tokenizer)
Definition index.php:144
static create(Tokenizer $tokenizer)
Definition procedure.php:29
createFromString($str, $delimiter)
Definition schema.php:59
executeCreateSequence(Tokenizer $tokenizer)
Definition schema.php:436
executeCreateTable(Tokenizer $tokenizer)
Definition schema.php:355
executeCreate(Tokenizer $tokenizer)
Definition schema.php:229
executeCreateProcedure(Tokenizer $tokenizer)
Definition schema.php:424
static create(Tokenizer $tokenizer)
Definition sequence.php:15
static create(Tokenizer $tokenizer)
Definition table.php:136
static createFromTokens(array $tokens)
Definition tokenizer.php:95
static searchTableName(Tokenizer $tokenizer)
Definition trigger.php:45