/** * Performs the actual optimization. In this case the optimizer looks * at the size of the column and the size of the value. If the value size is * smaller than the column size it tries to convert the column to a smaller * size. Next, it counts if there is any different between the smaller column * and the original column. If no differences are found the original column * gets replaced. * Like the other optimizers, this optimizer returns TRUE if it thinks * further optimizations can happen, FALSE otherwise. * * @return boolean $yesNo advance to next optimizer */ public function optimize() { //get the type of the current value $type = $this->writer->scanType($this->value); //get all the fields in the table $fields = $this->writer->getColumns($this->table); //If the column for some reason does not occur in fields, return if (!in_array($this->column, array_keys($fields))) { return false; } //get the type we got in the field of the table $typeInField = $this->writer->code($fields[$this->column]); //Is the type too wide? if ($type < $typeInField) { try { @$this->adapter->exec("alter table " . $this->writer->safeTable($this->table) . " drop __test"); } catch (Exception $e) { } //Try to re-fit the entire column; by testing it. $type = $this->writer->typeno_sqltype[$type]; //Add a test column. @$this->adapter->exec("alter table " . $this->writer->safeTable($this->table) . " add __test " . $type); //Copy the values and see if there are differences. @$this->adapter->exec("update " . $this->writer->safeTable($this->table) . " set __test=" . $this->writer->safeColumn($this->column) . ""); $rows = $this->adapter->get("select " . $this->writer->safeColumn($this->column) . " as a, __test as b from " . $this->writer->safeTable($this->table)); $diff = 0; foreach ($rows as $row) { $diff += $row["a"] != $row["b"]; } if (!$diff) { //No differences; shrink column. @$this->adapter->exec("alter table " . $this->writer->safeTable($this->table) . " change " . $this->writer->safeColumn($this->column) . " " . $this->writer->safeColumn($this->column) . " " . $type); } //Throw away test column; we don't need it anymore! @$this->adapter->exec("alter table " . $this->writer->safeTable($this->table) . " drop __test"); } return false; }
/** * Performs the actual optimization. In this case the optimizer looks * at the size of the column and the size of the value. If the value size is * smaller than the column size it tries to convert the column to a smaller * size. Next, it counts if there is any different between the smaller column * and the original column. If no differences are found the original column * gets replaced. * Like the other optimizers, this optimizer returns TRUE if it thinks * further optimizations can happen, FALSE otherwise. * * @return boolean $yesNo advance to next optimizer */ public function optimize() { $type = $this->writer->scanType($this->value); $fields = $this->writer->getColumns($this->table); if (!in_array($this->column,array_keys($fields))) return false; $typeInField = $this->writer->code($fields[$this->column]); if ($type < $typeInField) { try { @$this->adapter->exec("alter table ".$this->writer->noKW($this->table)." drop __test"); }catch(Exception $e) {} $type = $this->writer->typeno_sqltype[$type]; @$this->adapter->exec("alter table ".$this->writer->noKW($this->table)." add __test ".$type); @$this->adapter->exec("update ".$this->writer->noKW($this->table)." set __test=".$this->writer->noKW($this->column).""); $rows = $this->adapter->get("select ".$this->writer->noKW($this->column)." as a, __test as b from ".$this->writer->noKW($this->table)); $diff = 0; foreach($rows as $row) { $diff += ($row["a"]!=$row["b"]); } if (!$diff) { @$this->adapter->exec("alter table ".$this->writer->noKW($this->table)." change ".$this->writer->noKW($this->column)." ".$this->writer->noKW($this->column)." ".$type); } @$this->adapter->exec("alter table ".$this->writer->noKW($this->table)." drop __test"); } return false; }