8define(
'MAX_VARCHAR_LEN', 16383);
9define(
'CHAR_WIDTH', 4);
10define(
'CHARSET',
'utf8mb4');
11define(
'COLLATION',
'utf8mb4_0900_ai_ci');
13error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_WARNING & ~E_USER_WARNING & ~E_COMPILE_WARNING);
18 function ($class_name)
20 if (strpos(strtolower($class_name),
'bitrix\\perfmon\\') === 0)
22 $file_name = substr($class_name, strlen(
'bitrix\\perfmon\\'));
23 $file_name = strtolower(preg_replace(
'/(?<=[a-z])([A-Z])/',
'_$1', $file_name));
24 $file_name = str_replace(
'\\',
'/', $file_name);
25 require_once __DIR__ .
'/../../perfmon/lib/' . $file_name .
'.php';
40 if (preg_match(
'/^--file=(.+)$/', $argv[
$i], $match))
44 elseif (preg_match(
'/^--mysqldump=(.+)$/', $argv[
$i], $match))
48 elseif (preg_match(
'/^--host=(.+)$/', $argv[
$i], $match))
52 elseif (preg_match(
'/^--user=(.+)$/', $argv[
$i], $match))
56 elseif (preg_match(
'/^--password=(.+)$/', $argv[
$i], $match))
60 elseif (preg_match(
'/^--database=(.+)$/', $argv[
$i], $match))
64 elseif (preg_match(
'/^--table=(.+)$/', $argv[
$i], $match))
79 echo
"SET client_min_messages TO WARNING;\n";
84 while ($line = fgets(
$f))
86 if (preg_match(
'/^CREATE TABLE `(.*?)` /', $line, $match))
88 $tableName = $match[1];
94 if (preg_match(
'/^\)/', $line))
102 elseif (preg_match(
'/^(?:INSERT|REPLACE) INTO `(.*?)` VALUES (.+);\s*$/', $line, $match))
105 foreach (
$rows as $row)
107 echo
'INSERT INTO "' . $match[1] .
'" VALUES ' . $row .
";\n";
116 foreach (
$files as $file_name)
118 $sql = file_get_contents($file_name,
'r');
119 echo generate_schema_ddl($sql,
$table,
false, $file_name);
125 echo
"SET client_min_messages TO WARNING;\n";
128 $dbh->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
131 $r = $dbh->query(
'show databases');
132 while (
$a = $r->fetch(\PDO::FETCH_ASSOC))
135 $a[
'Database'] !==
'information_schema'
136 &&
$a[
'Database'] !==
'mysql'
137 &&
$a[
'Database'] !==
'performance_schema'
138 &&
$a[
'Database'] !==
'sys'
148 $dbh->exec(
'use ' . $db_name);
150 $r = $dbh->query(
'show tables');
151 while (
$a = $r->fetch(\PDO::FETCH_ASSOC))
153 $r2 = $dbh->query(
'show create table `' .
$a[
'Tables_in_' . $db_name] .
'`');
154 $a2 = $r2->fetch(\PDO::FETCH_ASSOC);
155 if (isset($a2[
'Table']))
157 $sql .= $a2[
'Create Table'] .
";\n";
160 echo generate_schema_ddl($sql,
$table,
true, $db_name);
166 return trim($identifier,
'`');
175 return $unsigned ?
'int' :
'smallint';
182 return $unsigned ?
'int8' :
'int';
187 return strtolower($columnType);
191 return 'double precision';
193 return 'char(' . $length .
')';
195 return 'varchar(' . $length .
')';
214 return '//unknown type ' . $columnType;
218function generate_schema_ddl($sql, $tableFilter, $isDump, $source)
224 $sql = str_replace(
'USING BTREE',
' ', $sql);
226 $s = new \Bitrix\Perfmon\Sql\Schema;
227 $s->createFromString($sql,
';');
229 foreach ($s->tables->getList() as
$table)
238 $ddl .=
'DROP TABLE IF EXISTS ' .
unquote(
$table->name) .
";\n";
241 $autoIncrementValue =
null;
242 $autoIncrementColumn =
'';
245 foreach (
$table->columns->getList() as $column)
247 $columnDefinition =
unquote($column->name);
248 if ($columnDefinition ===
'OFFSET' || $columnDefinition ===
'KEY')
250 $columnDefinition =
'"' . strtolower($columnDefinition) .
'"';
253 $hasAutoIncrement = preg_match(
'/AUTO_INCREMENT/i', $column->body) > 0;
254 if ($hasAutoIncrement && preg_match(
'/AUTO_INCREMENT=(\d+)/',
$table->body, $match))
256 $autoIncrementValue = $match[1];
257 $autoIncrementColumn =
unquote($column->name);
261 if (
$type ===
'enum' && $column->enum)
263 $enumType =
't_' . preg_replace(
'/^b_/i',
'',
unquote(
$table->name)) .
'_' .
unquote($column->name);
264 $ddl .=
'DROP TYPE IF EXISTS ' . $enumType .
";\n";
265 $ddl .=
'CREATE TYPE ' . $enumType .
" AS ENUM ('" . implode(
"', '", $column->enum) .
"');\n";
266 $columnDefinition .=
' ' . $enumType;
267 fwrite(STDERR,
'Warning: ' . $source .
': ' .
$table->name .
'.' . $column->name .
" is enum. Convert to char.\n");
271 $columnDefinition .=
' ' .
$type . ($hasAutoIncrement ?
' GENERATED BY DEFAULT AS IDENTITY' :
'');
274 if (!$column->nullable || $hasAutoIncrement)
276 $columnDefinition .=
' NOT NULL';
279 if ($column->unsigned)
281 fwrite(STDERR,
'Notice: ' . $source .
': ' .
$table->name .
'.' . $column->name .
" is unsigned. Consider to convert to wider type and remove unsigned defunition.\n");
284 if ($column->type ===
'TIMESTAMP')
286 $columnDefinition .=
' DEFAULT CURRENT_TIMESTAMP';
287 fwrite(STDERR,
'Warning: ' . $source .
': ' .
$table->name .
'.' . $column->name .
" is timestamp. Convert to datetime.\n");
289 elseif (!is_null($column->default) && strlen($column->default) > 0)
291 $default =
str_replace(
'"',
"'", $column->default);
292 $default =
str_replace(
"'0000-00-00 00:00:00'",
'', $default);
293 $default =
str_replace(
'NOW',
'CURRENT_TIMESTAMP', $default);
294 $default =
str_replace(
'now',
'CURRENT_TIMESTAMP', $default);
296 $default = trim($default,
" \t\n\r");
299 $columnDefinition .=
' DEFAULT ' . $default;
302 $inset[] = $columnDefinition;
306 foreach (
$table->constraints->getList() as $constraint)
308 if (preg_match(
'/^PRIMARY/i', $constraint->body) > 0)
310 $inset[] =
'PRIMARY KEY (' . implode(
', ', array_map(
313 return trim(
unquote(preg_replace(
'/\s+(desc|asc)/i',
'', preg_replace(
'/\(\d+\)/',
'', $x))),
" \t\n\r");
314 }, $constraint->columns)) .
')';
316 elseif (preg_match(
'/^UNIQUE/i', $constraint->body) > 0)
318 $inset[] =
'UNIQUE (' . implode(
', ', array_map(
322 }, $constraint->columns)) .
')';
330 $c =
count($inset) - 1;
331 foreach ($inset as
$i => $line)
333 $ddl .=
' ' . $line . (
$i < $c ?
',' :
'') .
"\n";
339 if ($autoIncrementValue && $isDump)
341 $ddl .=
'ALTER TABLE ' .
unquote(
$table->name) .
' ALTER COLUMN ' . $autoIncrementColumn .
' RESTART WITH ' . $autoIncrementValue .
";\n";
346 foreach (
$table->indexes->getList() as $index)
349 ($index->unique ?
'ux_' : ($index->fulltext ?
'tx_' :
'ix_'))
352 . implode(
'_', array_map(
355 return strtolower(
unquote(preg_replace(
'/\s*(\(\d+\)|asc|desc)(?![a-z0-9_])\s*/i',
'', $x)));
358 if (array_key_exists($indexName, $indexes))
360 $i = ++$indexes[$indexName];
362 $indexName = substr($indexName, 0, -strlen($suffix)) . $suffix;
366 $indexes[$indexName] = 0;
371 $ddl .=
'DROP INDEX IF EXISTS ' . $indexName .
";\n";
374 if ($index->fulltext)
376 $ddl .=
'CREATE INDEX ' . $indexName .
' ON ' .
unquote(
$table->name) .
" USING GIN (to_tsvector('english', " . implode(
' || ', array_map(
379 return strtolower(
unquote(preg_replace(
'/\s*(\(\d+\)|asc|desc)(?![a-z0-9_])\s*/i',
'', $x)));
380 }, $index->columns)) .
"));\n";
384 $ddl .=
'CREATE' . ($index->unique ?
' UNIQUE ' :
' ') .
'INDEX ' . $indexName .
' ON ' .
unquote(
$table->name) .
' (' . implode(
', ', array_map(
387 return strtolower(
unquote(preg_replace(
'/\s*(\(\d+\)|asc|desc)(?![a-z0-9_])\s*/i',
'', $x)));
388 }, $index->columns)) .
");\n";
397 static $search = [
'\\\'',
'\\"'];
398 static $replace = [
'\'\
'',
'"'];
400 $tokens = token_get_all(
'<?php ' . $values_str);
403 for (
$i = 1;
$i < $c;
$i++)
405 $token = $tokens[
$i];
407 ($token ==
',' || $token ==
';')
408 && ($tokens[
$i - 1] ==
')')
413 $result[] =
'(' . implode(
'', $row) .
')';
417 elseif ($token ==
'(' || $token ==
')')
423 if ($token[0] === T_CONSTANT_ENCAPSED_STRING)
425 $escaped = str_replace($search, $replace, $token[1]);
426 if ($escaped ===
"'0000-00-00 00:00:00'")
431 preg_match(
'/\\\\[bfnrt\']/', $escaped)
432 || strpos($escaped,
'\\\\') !==
false
435 $escaped =
'E' . $escaped;
439 elseif (preg_match(
'/^0x[0-9A-F]+$/', $token[1]))
441 $row[] =
'decode(\'' . substr($token[1], 2) .
'\', \
'hex\')';
455 $result[] =
'(' . implode(
'', $row) .
')';
static str_replace($search, $replace, $str)
parse_values($values_str)
for($i=1, $c=count($argv); $i< $c; $i++) if( $mysqldump) if($files) if( $host||$user||$password) unquote($identifier)
convertColumnType($columnType, $length, $unsigned)
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"