19declare(strict_types=1);
30 protected string $target_encoding =
'UTF-8';
31 protected array $whitelist = [];
32 protected array $blacklist = [];
33 protected array $tables = [];
34 protected array $filter = [];
39 protected array $allowed_attributes = [];
40 protected array $fields = [];
54 $this->allowed_attributes =
$ilDB->getAllowedAttributes();
61 public static function lookupAbstractedTables(): array
66 $query =
"SELECT DISTINCT(table_name) FROM abstraction_progress ";
70 $names[] = $row->table_name;
76 $abs_tables = array_merge($names, [
78 'acc_user_access_key',
81 'qpl_question_orderinghorizontal',
82 'qpl_question_fileupload',
85 'style_template_class',
89 'page_editor_settings',
100 'qpl_qst_fileupload',
104 'qpl_qst_javaapplet',
110 'qpl_qst_textsubset',
142 public function setTargetEncoding(
string $a_encoding): void
144 $this->target_encoding = $a_encoding;
147 public function getTargetEncoding(): string
149 return $this->target_encoding;
157 public function setBlackList(array $a_blacklist): void
159 $this->blacklist = $a_blacklist;
162 public function getBlackList(): array
164 return $this->blacklist;
173 public function setWhiteList(array $a_whitelist): void
175 $this->whitelist = $a_whitelist;
178 public function getWhiteList(): array
180 return $this->whitelist;
183 public function setFilter(
string $a_filter,
string $a_value): void
185 $this->
filter[$a_filter] = $a_value;
191 public function getTables(): array
193 return $this->tables = $this->manager->listTables();
199 public function checkProcessing(
string $a_table): bool
202 if (in_array($a_table, $this->blacklist,
true)) {
206 return !($this->whitelist !== [] && !in_array($a_table, $this->whitelist,
true));
212 protected function openFile(
string $a_path)
215 $file = fopen($a_path,
'wb');
216 $start .=
' global $ilDB;' .
"\n\n";
217 fwrite($file, $start);
225 protected function closeFile($fp): void
234 public function buildDBGenerationScript(
string $a_filename =
""): void
236 if (@is_dir($a_filename)) {
245 if ($a_filename !==
"" && !$is_dir) {
246 $file = fopen($a_filename,
'wb');
248 $start =
'<?php' .
"\n" .
'function setupILIASDatabase()' .
"\n{\n";
249 $start .=
' global $ilDB;' .
"\n\n";
250 fwrite($file, $start);
255 foreach ($this->getTables() as $table) {
256 if ($this->checkProcessing($table)) {
257 if ($a_filename !==
"") {
262 $file = $this->openFile(
$path .
'/' . $table);
266 $this->buildCreateTableStatement($table, $file);
269 $this->buildAddPrimaryKeyStatement($table, $file);
272 $this->buildAddIndexStatements($table, $file);
275 $this->buildAddUniqueConstraintStatements($table, $file);
278 $this->buildCreateSequenceStatement($table, $file);
280 if (in_array($table, [
'usr_session_stats',
'usr_session_raw',
'il_plugin'])) {
286 $this->buildInsertStatement($table,
$path);
287 #$this->buildInsertStatementsXML($table,$path);
289 $this->buildInsertStatements($table, $file);
293 $this->closeFile($file);
295 } elseif ($a_filename !==
"") {
296 echo
"<br><b>missing: " . $table .
"</b>";
302 $this->buildSingularSequenceStatement($file);
304 if ($a_filename ===
"") {
306 } elseif (!$is_dir) {
308 $ok = fwrite($file, $end);
318 public function buildCreateTableStatement(
string $a_table, $a_file =
null): void
320 $fields = $this->analyzer->getFieldInformation($a_table,
true);
321 $this->fields = $fields;
322 $create_st =
"\n\n//\n// " . $a_table .
"\n//\n";
323 $create_st .=
'$fields = array (' .
"\n";
325 foreach ($fields as
$f => $def) {
326 $create_st .=
"\t" . $f_sep .
'"' .
$f .
'" => array (' .
"\n";
329 foreach ($def as $k => $v) {
330 if ($k !==
"nativetype" && $k !==
"alt_types" && $k !==
"autoincrement" && !is_null($v)) {
335 $v = $v ?
"true" :
"false";
346 $create_st .=
"\t\t" . $a_sep .
'"' . $k .
'" => ' . $v .
"\n";
350 $create_st .=
' )' .
"\n";
352 $create_st .=
');' .
"\n";
353 $create_st .=
'$ilDB->createTable("' . $a_table .
'", $fields);' .
"\n";
355 if ($a_file ===
null) {
358 fwrite($a_file, $create_st);
365 public function buildAddPrimaryKeyStatement(
string $a_table, $a_file =
null): void
367 $pk = $this->analyzer->getPrimaryKeyInformation($a_table);
369 if (isset($pk[
"fields"]) && is_array($pk[
"fields"]) && $pk[
"fields"] !== []) {
370 $pk_st =
"\n" .
'$pk_fields = array(';
372 foreach (array_keys($pk[
"fields"]) as
$f) {
373 $pk_st .= $sep .
'"' .
$f .
'"';
377 $pk_st .=
'$ilDB->addPrimaryKey("' . $a_table .
'", $pk_fields);' .
"\n";
379 if ($a_file ===
null) {
382 fwrite($a_file, $pk_st);
390 public function buildAddIndexStatements(
string $a_table, $a_file =
null): void
392 $ind = $this->analyzer->getIndicesInformation($a_table,
true);
394 if (is_array($ind)) {
395 foreach ($ind as $i) {
396 $ft = $i[
"fulltext"] ?
", true" :
", false";
397 $in_st =
"\n" .
'$in_fields = array(';
399 foreach ($i[
"fields"] as
$f => $pos) {
400 $in_st .= $sep .
'"' .
$f .
'"';
404 $in_st .=
'$ilDB->addIndex("' . $a_table .
'", $in_fields, "' . $i[
"name"] .
'"' . $ft .
');' .
"\n";
406 if ($a_file ===
null) {
409 fwrite($a_file, $in_st);
418 private function printOrWrite(
string $string, $file_handle =
null): void
420 if ($file_handle ===
null) {
423 fwrite($file_handle, $string);
430 public function buildAddUniqueConstraintStatements(
string $a_table, $file_handle =
null): void
432 $con = $this->analyzer->getConstraintsInformation($a_table,
true);
434 if (is_array($con)) {
436 foreach ($con as $i) {
437 $in_st =
"\n" .
'$in_fields = array(';
439 foreach ($i[
"fields"] as
$f => $pos) {
440 $in_st .= $sep .
'"' .
$f .
'"';
444 $in_st .=
'$ilDB->addUniqueConstraint("' . $a_table .
'", $in_fields, "' . $i[
"name"] .
'");' .
"\n";
446 $this->printOrWrite($in_st, $file_handle);
454 public function buildCreateSequenceStatement(
string $a_table, $file_handle =
null): void
456 $seq = $this->analyzer->hasSequence($a_table);
457 if ($seq !==
false) {
458 $seq_st =
"\n" .
'$ilDB->createSequence("' . $a_table .
'", ' . (
int) $seq .
');' .
"\n";
460 $this->printOrWrite($seq_st, $file_handle);
467 public function buildSingularSequenceStatement($file_handle =
null): void
469 $r = $this->manager->listSequences();
471 foreach ($r as $seq) {
472 if (!in_array($seq, $this->tables,
true)) {
474 if ($seq ===
"sahs_sc13_seq") {
478 $create_st =
"\n" .
'$ilDB->createSequence("' . $seq .
'");' .
"\n";
480 $this->printOrWrite($create_st, $file_handle);
488 public function buildInsertStatement(
string $a_table,
string $a_basedir): bool
491 $ilLogger =
$DIC->logger()->root();
493 $ilLogger->log(
'Starting export of:' . $a_table);
495 $set = $this->il_db->query(
"SELECT * FROM " . $this->il_db->quoteIdentifier($a_table));
500 $concurrentDirectory = $a_basedir .
'/' . $a_table .
'_inserts',
501 fileperms($a_basedir)
502 ) && !is_dir($concurrentDirectory)) {
503 throw new \RuntimeException(sprintf(
'Directory "%s" was not created', $concurrentDirectory));
507 while ($rec = $this->il_db->fetchAssoc($set)) {
509 foreach ($rec as
$f => $v) {
510 if ($this->fields[
$f][
'type'] ===
'text' && $this->fields[
$f][
'length'] >= 1000) {
511 $v = $this->shortenText($a_table,
$f, $v, $this->fields[
$f][
'length']);
515 $this->fields[
$f][
'type'],
520 $rows[$a_table][$row++] = $values;
523 $ilLogger->log(
'Writing insert statements after 1000 lines...');
524 $fp = fopen($a_basedir .
'/' . $a_table .
'_inserts/' . $filenum++ .
'.data',
'wb');
525 fwrite($fp, serialize($rows));
533 $fp = fopen($a_basedir .
'/' . $a_table .
'_inserts/' . $filenum++ .
'.data',
'wb');
534 fwrite($fp, serialize($rows) .
"\n");
538 $ilLogger->log(
'Finished export of: ' . $a_table);
539 if (function_exists(
'memory_get_usage')) {
540 $ilLogger->log(
'Memory usage: ' . memory_get_usage(
true));
549 public function buildInsertStatements(
string $a_table, $file_handle =
null): void
551 if ($a_table ===
"lng_data") {
555 $set = $this->il_db->query(
"SELECT * FROM " . $this->il_db->quoteIdentifier($a_table));
557 while ($rec = $this->il_db->fetchAssoc($set)) {
562 foreach ($rec as
$f => $v) {
563 $v = str_replace(
'\\',
'\\\\', $v);
564 $i_str[] =
"'" .
$f .
"' => array('" . $this->fields[
$f][
"type"] .
"', '" . str_replace(
570 $ins_st =
"\n" .
'$ilDB->insert("' . $a_table .
'", array(' .
"\n";
571 $ins_st .= implode(
", ", $i_str) .
"));\n";
573 $this->printOrWrite($ins_st, $file_handle);
581 protected function shortenText(
string $table,
string $field,
string $a_value,
int $a_size): string
584 $ilLogger =
$DIC->logger()->root();
586 if ($this->getTargetEncoding() ===
'UTF-8') {
590 $shortened = mb_convert_encoding($a_value, $this->getTargetEncoding(),
'UTF-8');
594 $shortened = mb_convert_encoding($shortened,
'UTF-8', $this->getTargetEncoding());
596 if (strlen($a_value) !== strlen($shortened)) {
597 $ilLogger->log(
'Table : ' . $table);
598 $ilLogger->log(
'Field : ' . $field);
599 $ilLogger->log(
'Type : ' . $this->fields[$field][
'type']);
600 $ilLogger->log(
'Length : ' . $this->fields[$field][
'length']);
601 $ilLogger->log(
'Before : ' . $a_value);
602 $ilLogger->log(
'Shortened : ' . $shortened);
603 $ilLogger->log(
'Strlen Before: ' . strlen($a_value));
604 $ilLogger->log(
'Strlen After : ' . strlen($shortened));
This class gives all kind of DB information using the database manager and reverse module.
static shortenText(string $a_string, int $a_start_pos, int $a_num_bytes, string $a_encoding='UTF-8')
Shorten text to the given number of bytes.
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
filter(string $filter_id, $class_path, string $cmd, bool $activated=true, bool $expanded=true)