/** * @expectedException \Thru\ActiveRecord\DatabaseLayer\Exception * @expectedExceptionMessage Query made PDO sad: */ public function testTableExistsFailure() { //$this->markTestSkipped("Disabled until further notice. This exposed an actual PHP bug. See: https://bugs.php.net/bug.php?id=69063"); $database = DatabaseLayer::getInstance(); $select = $database->select("table_doesnt_exist"); $select->execute("NotStdClass"); }
public function testWorksWithoutMonolog() { $logger = DatabaseLayer::getInstance()->getLogger(); DatabaseLayer::getInstance()->setLogger(null); TestModel::search()->exec(); DatabaseLayer::getInstance()->setLogger($logger); }
public function save($automatic_reload = true) { $databaseLayer = DatabaseLayer::getInstance(); $lockController = $databaseLayer->lockController($this->getTable(), $this->getTableAlias()); // Check the table exists. $this->getTableBuilder()->build(); // Lock the table. $lockController->lock(); // Get our primary key $primaryColumn = $this->getIDField(); // Get the highest primary key if (!$this->{$primaryColumn}) { $highest = DumbModel::query("SELECT max({$primaryColumn}) as highest FROM {$this->getTable()}"); $highestKey = end($highest)->highest; // Set our primary key to this +1 $newKey = isset($highestKey) ? $highestKey + 1 : 1; $this->{$primaryColumn} = $newKey; // echo "{$this->get_table()}: {$primaryColumn} = {$newKey}\n"; } // Set sequence to sequence + 1 $highestSequence = DumbModel::query("SELECT max(sequence) as highest FROM {$this->getTable()} WHERE `{$primaryColumn}` = '{$this->{$primaryColumn}}'"); $highestSequenceKey = end($highestSequence)->highest; if (!$highestSequenceKey) { $this->sequence = 1; } else { $this->sequence = intval($highestSequenceKey) + 1; } // Save the object parent::save($automatic_reload); // Unlock the table. $lockController->unlock(); // return the object. return $this; }
/** * @expectedException \Thru\ActiveRecord\DatabaseLayer\TableDoesntExistException */ public function testIndexFailOnNonExistant() { if (DatabaseLayer::getInstance()->getOption('db_type') !== "mysql") { $this->markTestSkipped("MySQL Dependent"); } $mysql = new \Thru\ActiveRecord\DatabaseLayer\Sql\Mysql(); $mysql->getIndexes("test_models_sortable"); }
public function exec() { $primary_key_search = false; if (count($this->conditions) == 1) { /* @var $model ActiveRecord */ $model = $this->model; if (end($this->conditions)->getColumn() == $model->getIDField() && end($this->conditions)->getOperation() == '=') { $primary_key_search = true; // TODO: write a test to verify that the additional class ahead of the table name fixes this bug. if (SearchIndex::getInstance()->exists(get_class($model) . "/" . $model->getTableName(), end($this->conditions)->getValue())) { return [SearchIndex::getInstance()->get(get_class($model) . "/" . $model->getTableName(), end($this->conditions)->getValue())]; } } unset($model); } $database = DatabaseLayer::getInstance(); $select = $database->select($this->model->getTableName(), $this->model->getTableAlias()); $select->fields($this->model->getTableAlias()); // Add WHERE Conditions foreach ((array) $this->conditions as $condition) { $select->condition($condition->getColumn(), $condition->getValue(), $condition->getOperation()); } if ($this->order) { foreach ($this->order as $order) { $select->orderBy($order['column'], $order['direction']); } } // Build LIMIT SQL if relevent if ($this->limit) { $select->range($this->offset, $this->limit); } // Get objects $class = get_class($this->model); $select->setModel($class); $response = $select->execute(); return $this->execProcessResponse($response, $primary_key_search); }
public function handleError($model, $query, \PDOException $e) { // echo "*** Model in handleError: " . $model . "\n"; switch ($e->getCode()) { // MySQL table missing case '42S02': // SQLite table missing // SQLite table missing case 'HY000' && stripos($e->getMessage(), "no such table") !== false: if ($model != 'StdClass') { $instance = new $model(); if ($instance instanceof ActiveRecord) { $table_builder = new TableBuilder($instance); $table_builder->build(); return $this->query($query, $model); // Re-run the query } } throw new DatabaseLayer\TableDoesntExistException($e->getCode() . ": " . $e->getMessage()); default: // Write exception to log. if (DatabaseLayer::getInstance()->getLogger()) { DatabaseLayer::getInstance()->getLogger()->addError("Active Record Exception in " . $model . "\n\n" . $e->getCode() . ": " . $e->getMessage() . "\n\nrunning:\n\n{$query}"); } throw new DatabaseLayer\Exception($e->getCode() . ": " . $e->getMessage() . ".\n\n" . $query); } }
public function buildTable(ActiveRecord $model) { $schema = $model->getClassSchema(); $params = array(); foreach ($model->__calculateSaveDownRows() as $p => $parameter) { $auto_increment = false; $type = "varchar(200)"; $auto_increment_possible = false; if (isset($schema[$parameter])) { $psuedo_type = $schema[$parameter]['type']; switch (strtolower($psuedo_type)) { case 'int': case 'integer': $length = isset($schema[$parameter]['length']) ? $schema[$parameter]['length'] : 10; $type = "INT"; $auto_increment_possible = true; break; case 'string': $length = isset($schema[$parameter]['length']) ? $schema[$parameter]['length'] : 200; $type = "VARCHAR({$length})"; break; case 'date': case 'datetime': $type = 'TIME'; break; case 'enum': $type = "ENUM('" . implode("', '", $schema[$parameter]['options']) . "')"; break; case 'text': $type = "TEXT"; break; case 'blob': $type = 'BLOB'; break; case "decimal": $type = "DECIMAL(" . implode(",", $schema[$parameter]['options']) . ")"; break; case "uuid": $type = "VARCHAR(" . strlen(UUID::v4()) . ")"; break; case "md5": $type = "VARCHAR(" . strlen(md5("test")) . ")"; break; case "sha1": $type = "VARCHAR(" . strlen(sha1("test")) . ")"; break; } } if ($p == 0) { // First param always primary key if possible if ($auto_increment_possible) { $primary_key = $parameter; if (!$model instanceof VersionedActiveRecord) { $auto_increment = true; } } } if ($auto_increment) { $type = 'SERIAL'; } $nullability = $schema[$parameter]['nullable'] ? "NULL" : "NOT NULL"; $params[] = " " . trim("\"{$parameter}\" {$type} {$nullability}"); } // Disable auto-increment if this object is versioned. if ($model instanceof VersionedActiveRecord) { if (isset($primary_key)) { $params[] = " PRIMARY KEY (\"{$primary_key}\", \"sequence\")"; } } else { if (isset($primary_key)) { $params[] = " PRIMARY KEY (\"{$primary_key}\")"; } } $query = "CREATE TABLE IF NOT EXISTS \"{$model->getTableName()}\"\n"; $query .= "(\n"; $query .= implode(",\n", $params) . "\n"; $query .= ");\n"; // Log it. if (DatabaseLayer::getInstance()->getLogger() instanceof Logger) { DatabaseLayer::getInstance()->getLogger()->addInfo("Creating table {$model->getTableName()}\n\n{$query}"); } $this->query($query); }
public function buildTable(ActiveRecord $model) { $schema = $model->getClassSchema(); $params = array(); foreach ($model->__calculateSaveDownRows() as $p => $parameter) { $auto_increment = false; $type = "varchar(200)"; $auto_increment_possible = false; if (isset($schema[$parameter])) { $psuedo_type = $schema[$parameter]['type']; switch (strtolower($psuedo_type)) { case 'int': case 'integer': $type = "INTEGER"; $auto_increment_possible = true; break; case 'date': case 'datetime': case 'enum': case 'string': case 'text': case 'uuid': case 'md5': case 'sha1': $type = "TEXT"; break; case 'blob': $type = 'BLOB'; break; } } $is_primary_key = false; if ($p == 0) { // First param always primary key if possible if ($auto_increment_possible) { $is_primary_key = "PRIMARY KEY"; if (!$model instanceof VersionedActiveRecord) { $auto_increment = true; } } } if ($auto_increment && !$model instanceof VersionedActiveRecord) { $auto_increment_sql = 'AUTOINCREMENT'; } else { $auto_increment_sql = false; } $nullability = $schema[$parameter]['nullable'] ? "NULL" : "NOT NULL"; $nullability = $is_primary_key ? '' : $nullability; $is_primary_key = !$model instanceof VersionedActiveRecord ? $is_primary_key : null; $params[] = " " . trim("`{$parameter}` {$type} {$is_primary_key} {$auto_increment_sql} {$nullability}"); } $query = "CREATE TABLE IF NOT EXISTS `{$model->getTableName()}`\n"; $query .= "(\n"; $query .= implode(",\n", $params) . "\n"; $query .= ")\n"; $this->query($query); // Log it. if (DatabaseLayer::getInstance()->getLogger() instanceof Logger) { DatabaseLayer::getInstance()->getLogger()->addInfo("Creating table {$model->getTableName()}\n\n{$query}"); } }
/** * @expectedException \Thru\ActiveRecord\DatabaseLayer\ConfigurationException * @expectedExceptionMessage DatabaseLayer has not been configured */ public function testBlankDatabaseLayer() { DatabaseLayer::getInstance(); }
/** * Delete the selected record * @return boolean */ public function delete() { $database = DatabaseLayer::getInstance(); $delete = $database->delete($this->getTableName(), $this->getTableAlias()); $delete->setModel($this); $delete->condition($this->getIDField(), $this->getId()); $delete->execute($this->getClass()); // Invalidate cache. SearchIndex::getInstance()->expire($this->getTableName(), $this->getId()); return true; }
/** * @return \Thru\ActiveRecord\DatabaseLayer\Sql\Base */ public function getInterpreter() { $sql_interpreter_name = "\\Thru\\ActiveRecord\\DatabaseLayer\\Sql\\" . \Thru\ActiveRecord\DatabaseLayer::getInstance()->getOption('db_type'); $sql_interpreter = $sql_interpreter_name::factory(); return $sql_interpreter; }