protected function check_table(xmldb_table $xmldb_table, array $metacolumns) { $o = ''; $wrong_fields = array(); // Get and process XMLDB fields if ($xmldb_fields = $xmldb_table->getFields()) { $o .= ' <ul>'; foreach ($xmldb_fields as $xmldb_field) { // Get the default value for the field $xmldbdefault = $xmldb_field->getDefault(); // If the metadata for that column doesn't exist or 'id' field found, skip if (!isset($metacolumns[$xmldb_field->getName()]) or $xmldb_field->getName() == 'id') { continue; } // To variable for better handling $metacolumn = $metacolumns[$xmldb_field->getName()]; // Going to check this field in DB $o .= ' <li>' . $this->str['field'] . ': ' . $xmldb_field->getName() . ' '; // get the value of the physical default (or blank if there isn't one) if ($metacolumn->has_default == 1) { $physicaldefault = $metacolumn->default_value; } else { $physicaldefault = ''; } // there *is* a default and it's wrong if ($physicaldefault != $xmldbdefault) { $info = '(' . $this->str['expected'] . " '{$xmldbdefault}', " . $this->str['actual'] . " '{$physicaldefault}')"; $o .= '<font color="red">' . $this->str['wrong'] . " {$info}</font>"; // Add the wrong field to the list $obj = new stdClass(); $obj->table = $xmldb_table; $obj->field = $xmldb_field; $obj->physicaldefault = $physicaldefault; $obj->xmldbdefault = $xmldbdefault; $wrong_fields[] = $obj; } else { $o .= '<font color="green">' . $this->str['ok'] . '</font>'; } $o .= '</li>'; } $o .= ' </ul>'; } return array($o, $wrong_fields); }
protected function check_table(xmldb_table $xmldb_table, array $metacolumns) { $o = ''; $wrong_fields = array(); // Get and process XMLDB fields if ($xmldb_fields = $xmldb_table->getFields()) { $o .= ' <ul>'; foreach ($xmldb_fields as $xmldb_field) { // If the field isn't integer(10), skip if ($xmldb_field->getType() != XMLDB_TYPE_INTEGER) { continue; } // If the metadata for that column doesn't exist, skip if (!isset($metacolumns[$xmldb_field->getName()])) { continue; } $minlength = $xmldb_field->getLength(); if ($minlength > 18) { // Anything above 18 is borked, just ignore it here. $minlength = 18; } // To variable for better handling $metacolumn = $metacolumns[$xmldb_field->getName()]; // Going to check this field in DB $o .= ' <li>' . $this->str['field'] . ': ' . $xmldb_field->getName() . ' '; // Detect if the physical field is wrong if ($metacolumn->meta_type != 'I' and $metacolumn->meta_type != 'R' or $metacolumn->max_length < $minlength) { $o .= '<font color="red">' . $this->str['wrong'] . '</font>'; // Add the wrong field to the list $obj = new stdClass(); $obj->table = $xmldb_table; $obj->field = $xmldb_field; $wrong_fields[] = $obj; } else { $o .= '<font color="green">' . $this->str['ok'] . '</font>'; } $o .= '</li>'; } $o .= ' </ul>'; } return array($o, $wrong_fields); }
protected function check_table(xmldb_table $xmldb_table, array $metacolumns) { global $DB; $o = ''; $wrong_fields = array(); // Get and process XMLDB fields if ($xmldb_fields = $xmldb_table->getFields()) { $o .= '<ul>'; foreach ($xmldb_fields as $xmldb_field) { // Get the type of the column, we only will process CHAR (VARCHAR2) ones if ($xmldb_field->getType() != XMLDB_TYPE_CHAR) { continue; } $o .= '<li>' . $this->str['field'] . ': ' . $xmldb_field->getName() . ' '; // Get current semantic from dictionary, we only will process B (BYTE) ones // suplying the SQL code to change them to C (CHAR) semantic $params = array('table_name' => core_text::strtoupper($DB->get_prefix() . $xmldb_table->getName()), 'column_name' => core_text::strtoupper($xmldb_field->getName()), 'data_type' => 'VARCHAR2'); $currentsemantic = $DB->get_field_sql(' SELECT char_used FROM user_tab_columns WHERE table_name = :table_name AND column_name = :column_name AND data_type = :data_type', $params); // If using byte semantics, we'll need to change them to char semantics if ($currentsemantic == 'B') { $info = '(' . $this->str['expected'] . " 'CHAR', " . $this->str['actual'] . " 'BYTE')"; $o .= '<font color="red">' . $this->str['wrong'] . " {$info}</font>"; // Add the wrong field to the list $obj = new stdClass(); $obj->table = $xmldb_table; $obj->field = $xmldb_field; $wrong_fields[] = $obj; } else { $o .= '<font color="green">' . $this->str['ok'] . '</font>'; } $o .= '</li>'; } $o .= '</ul>'; } return array($o, $wrong_fields); }
protected function check_table(xmldb_table $xmldb_table, array $metacolumns) { $o = ''; $wrong_fields = array(); /// Get and process XMLDB fields if ($xmldb_fields = $xmldb_table->getFields()) { $o .= ' <ul>'; foreach ($xmldb_fields as $xmldb_field) { /// If the field isn't integer(10), skip if ($xmldb_field->getType() != XMLDB_TYPE_INTEGER || $xmldb_field->getLength() != 10) { continue; } /// If the metadata for that column doesn't exist, skip if (!isset($metacolumns[$xmldb_field->getName()])) { continue; } /// To variable for better handling $metacolumn = $metacolumns[$xmldb_field->getName()]; /// Going to check this field in DB $o .= ' <li>' . $this->str['field'] . ': ' . $xmldb_field->getName() . ' '; /// Detect if the phisical field is wrong and, under mysql, check for incorrect signed fields too if ($metacolumn->type != $this->correct_type || $this->dbfamily == 'mysql' && $xmldb_field->getUnsigned() && !$metacolumn->unsigned) { $o .= '<font color="red">' . $this->str['wrong'] . '</font>'; /// Add the wrong field to the list $obj = new object(); $obj->table = $xmldb_table; $obj->field = $xmldb_field; $wrong_fields[] = $obj; } else { $o .= '<font color="green">' . $this->str['ok'] . '</font>'; } $o .= '</li>'; } $o .= ' </ul>'; } return array($o, $wrong_fields); }
/** * Given one correct xmldb_table, returns the SQL statements * to create it (inside one array). * * @param xmldb_table $xmldb_table An xmldb_table instance. * @return array An array of SQL statements, starting with the table creation SQL followed * by any of its comments, indexes and sequence creation SQL statements. */ public function getCreateTableSQL($xmldb_table) { // First find out if want some special db engine. $engine = $this->mdb->get_dbengine(); // Do we know collation? $collation = $this->mdb->get_dbcollation(); // Do we need to use compressed format for rows? $rowformat = ""; $size = $this->guess_antolope_row_size($xmldb_table->getFields()); if ($size > self::ANTELOPE_MAX_ROW_SIZE) { if ($this->mdb->is_compressed_row_format_supported()) { $rowformat = "\n ROW_FORMAT=Compressed"; } } $sqlarr = parent::getCreateTableSQL($xmldb_table); // This is a very nasty hack that tries to use just one query per created table // because MySQL is stupidly slow when modifying empty tables. // Note: it is safer to inject everything on new lines because there might be some trailing -- comments. $sqls = array(); $prevcreate = null; $matches = null; foreach ($sqlarr as $sql) { if (preg_match('/^CREATE TABLE ([^ ]+)/', $sql, $matches)) { $prevcreate = $matches[1]; $sql = preg_replace('/\\s*\\)\\s*$/s', '/*keyblock*/)', $sql); // Let's inject the extra MySQL tweaks here. if ($engine) { $sql .= "\n ENGINE = {$engine}"; } if ($collation) { if (strpos($collation, 'utf8_') === 0) { $sql .= "\n DEFAULT CHARACTER SET utf8"; } $sql .= "\n DEFAULT COLLATE = {$collation}"; } if ($rowformat) { $sql .= $rowformat; } $sqls[] = $sql; continue; } if ($prevcreate) { if (preg_match('/^ALTER TABLE ' . $prevcreate . ' COMMENT=(.*)$/s', $sql, $matches)) { $prev = array_pop($sqls); $prev .= "\n COMMENT={$matches['1']}"; $sqls[] = $prev; continue; } if (preg_match('/^CREATE INDEX ([^ ]+) ON ' . $prevcreate . ' (.*)$/s', $sql, $matches)) { $prev = array_pop($sqls); if (strpos($prev, '/*keyblock*/')) { $prev = str_replace('/*keyblock*/', "\n, KEY {$matches['1']} {$matches['2']}/*keyblock*/", $prev); $sqls[] = $prev; continue; } else { $sqls[] = $prev; } } if (preg_match('/^CREATE UNIQUE INDEX ([^ ]+) ON ' . $prevcreate . ' (.*)$/s', $sql, $matches)) { $prev = array_pop($sqls); if (strpos($prev, '/*keyblock*/')) { $prev = str_replace('/*keyblock*/', "\n, UNIQUE KEY {$matches['1']} {$matches['2']}/*keyblock*/", $prev); $sqls[] = $prev; continue; } else { $sqls[] = $prev; } } } $prevcreate = null; $sqls[] = $sql; } foreach ($sqls as $key => $sql) { $sqls[$key] = str_replace('/*keyblock*/', "\n", $sql); } return $sqls; }
/** * Given one correct xmldb_table, returns the SQL statements * to create it (inside one array). * * @param xmldb_table $xmldb_table An xmldb_table instance. * @return array An array of SQL statements, starting with the table creation SQL followed * by any of its comments, indexes and sequence creation SQL statements. */ public function getCreateTableSQL($xmldb_table) { // First find out if want some special db engine. $engine = $this->mdb->get_dbengine(); // Do we know collation? $collation = $this->mdb->get_dbcollation(); // Do we need to use compressed format for rows? $rowformat = ""; $size = $this->guess_antolope_row_size($xmldb_table->getFields()); if ($size > self::ANTELOPE_MAX_ROW_SIZE) { if ($this->mdb->is_compressed_row_format_supported()) { $rowformat = "\n ROW_FORMAT=Compressed"; } } $sqlarr = parent::getCreateTableSQL($xmldb_table); // Let's inject the extra MySQL tweaks. foreach ($sqlarr as $i => $sql) { if (strpos($sql, 'CREATE TABLE ') === 0) { if ($engine) { $sqlarr[$i] .= " ENGINE = {$engine}"; } if ($collation) { if (strpos($collation, 'utf8_') === 0) { $sqlarr[$i] .= " DEFAULT CHARACTER SET utf8"; } $sqlarr[$i] .= " DEFAULT COLLATE = {$collation}"; } if ($rowformat) { $sqlarr[$i] .= $rowformat; } } } return $sqlarr; }