/** * Does an optimization cycle for each UPDATE event * @param string $event * @param RedBean_OODBBean $bean */ public function onEvent($event, $bean) { try { if ($event == "update") { $arr = $bean->export(); unset($arr["id"]); if (count($arr) == 0) { return; } $table = $this->adapter->escape($bean->getMeta("type")); $columns = array_keys($arr); $column = $this->adapter->escape($columns[array_rand($columns)]); $value = $arr[$column]; $type = $this->writer->scanType($value); $fields = $this->writer->getColumns($table); if (!in_array($column, array_keys($fields))) { return; } $typeInField = $this->writer->code($fields[$column]); if ($type < $typeInField) { $type = $this->writer->typeno_sqltype[$type]; $this->adapter->exec("alter table `{$table}` add __test " . $type); $this->adapter->exec("update `{$table}` set __test=`{$column}`"); $diff = $this->adapter->getCell("select\n\t\t\t\t\t\t\tcount(*) as df from `{$table}` where\n\t\t\t\t\t\t\tstrcmp(`{$column}`,__test) != 0"); if (!$diff) { $this->adapter->exec("alter table `{$table}` change `{$column}` `{$column}` " . $type); } $this->adapter->exec("alter table `{$table}` drop __test"); } } } catch (RedBean_Exception_SQL $e) { //optimizer might make mistakes, dont care.. } }
/** * Gets information about changed records using a type and id and a logid. * RedBean Locking shields you from race conditions by comparing the latest * cached insert id with a the highest insert id associated with a write action * on the same table. If there is any id between these two the record has * been changed and RedBean will throw an exception. This function checks for changes. * If changes have occurred it will throw an exception. If no changes have occurred * it will insert a new change record and return the new change id. * This method locks the log table exclusively. * @param string $type * @param integer $id * @param integer $logid * @return integer $newchangeid */ public function checkChanges($type, $id, $logid) { $type = $this->check($type); $id = (int) $id; $logid = (int) $logid; $num = $this->adapter->getCell("\n SELECT count(*) FROM __log WHERE tbl=\"{$type}\" AND itemid={$id} AND action=2 AND id > {$logid}"); if ($num) { throw new RedBean_Exception_FailedAccessBean("Locked, failed to access (type:{$type}, id:{$id})"); } $newid = $this->insertRecord("__log", array("action", "tbl", "itemid"), array(array(2, $type, $id))); if ($this->adapter->getCell("select id from __log where tbl=:tbl AND id < {$newid} and id > {$logid} and action=2 and itemid={$id} ", array(":tbl" => $type))) { throw new RedBean_Exception_FailedAccessBean("Locked, failed to access II (type:{$type}, id:{$id})"); } return $newid; }
/** * Convenience function to execute Queries directly. * Executes SQL. * * @param string $sql sql * @param array $values values * * @return string $result scalar */ public static function getCell($sql, $values = array()) { if (!self::$redbean->isFrozen()) { try { $rs = RedBean_Facade::$adapter->getCell($sql, $values); } catch (RedBean_Exception_SQL $e) { if (self::$writer->sqlStateIn($e->getSQLState(), array(RedBean_QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN, RedBean_QueryWriter::C_SQLSTATE_NO_SUCH_TABLE))) { return NULL; } else { throw $e; } } return $rs; } else { return RedBean_Facade::$adapter->getCell($sql, $values); } }
/** * @see RedBean_QueryWriter::addIndex */ public function addIndex($type, $name, $column) { $table = $type; $table = $this->esc($table); $name = preg_replace('/\\W/', '', $name); $column = $this->esc($column); if ($this->adapter->getCell("SELECT COUNT(*) FROM pg_class WHERE relname = '{$name}'")) { return; } try { $this->adapter->exec("CREATE INDEX {$name} ON {$table} ({$column}) "); } catch (Exception $e) { } }
/** * Convenience function to execute Queries directly. * Executes SQL. * * @param string $sql sql * @param array $values values * * @return string $result scalar */ public static function getCell( $sql, $values=array() ) { return self::secureExec(function($sql, $values) { return R::$adapter->getCell( $sql, $values ); }, NULL, $sql, $values); }