librenms/LibreNMS/Model.php
Tony Murray 11147d3bbf
Major Processors rewrite (#8066)
* Extract DiscoveryItem and move some things to better places.
Extract model class
Fix up model construction.  I have problem with construction...
Makeshift model working.  Switch constructor to factory.  discover() and create()
Support legacy discovery.
Remove uneeded custom pollers
Remove netonix custom detection as we try ucd on all os now.
Add a few yaml procs.  Fix a couple things.
More processor discovery conversions
Move Calix e7 to standard hrProcessorLoad, but it doesn't fully implement the HR-MIB, move things around to make it work.
Add a few yaml procs.  Fix a couple things. Correct some stupid mib stuff.
Move more, drop php 5.3
Add netscaler which uses string indexes.  Port fiberhome to yaml and use skip_values
More conversions.  BroadcomProcessorUsage Trait
Serveriron and Ironware share some mibs.  Create a common abstract os for them.
Add yaml support for mib specification in each data entry
Make legacy discover_processor() set 0 for hrDeviceIndex

Untangle Dell switch OS processors

Use use shared OS for groups if they don't have a specific group.
fix silly mib mistake

Make index optional

Move HR and UCD to Traits and out of Processor.

* forgot to update the fortiswitch index

* Make sgos and avaya-ers match the old index.

* fix comware test data

* fix merge errors

* fix dsm and remove pointless empty modules

* file not found exception is in the wrong place.

* Updated processor development docs
2018-02-05 07:39:13 -06:00

203 lines
5.3 KiB
PHP

<?php
namespace LibreNMS;
abstract class Model
{
protected static $table;
protected static $primaryKey = 'id';
public static function create(array $data)
{
$instance = new static();
$instance->fill($data);
return $instance;
}
protected function fill(array $data = array())
{
foreach ($data as $field => $value) {
$this->$field = $value;
}
}
/**
* Save Models and remove invalid Models
* This the sensors array should contain all the sensors of a specific class
* It may contain sensors from multiple tables and devices, but that isn't the primary use
*
* @param int $device_id
* @param array $models
* @param array $unique_fields fields to search for an existing entry
* @param array $ignored_update_fields Don't compare these field when updating
*/
final public static function sync($device_id, array $models, $unique_fields = array(), $ignored_update_fields = array())
{
// save and collect valid ids
$valid_ids = array();
foreach ($models as $model) {
/** @var $this $model */
if ($model->isValid()) {
$valid_ids[] = $model->save($unique_fields, $ignored_update_fields);
}
}
// delete invalid sensors
self::clean($device_id, $valid_ids);
}
/**
* Remove invalid Models. Passing an empty array will remove all models related to $device_id
*
* @param int $device_id
* @param array $model_ids valid Model ids
*/
protected static function clean($device_id, $model_ids)
{
$table = static::$table;
$key = static::$primaryKey;
$params = array($device_id);
$where = '`device_id`=?';
if (!empty($model_ids)) {
$where .= " AND `$key` NOT IN " . dbGenPlaceholders(count($model_ids));
$params = array_merge($params, $model_ids);
}
$rows = dbFetchRows("SELECT * FROM `$table` WHERE $where", $params);
foreach ($rows as $row) {
static::onDelete(static::create($row));
}
if (!empty($rows)) {
dbDelete($table, $where, $params);
}
}
/**
* Save this Model to the database.
*
* @param array $unique_fields fields to search for an existing entry
* @param array $ignored_update_fields Don't compare these field when updating
* @return int the id of this model in the database
*/
final public function save($unique_fields = array(), $ignored_update_fields = array())
{
$db_model = $this->fetch($unique_fields);
$key = static::$primaryKey;
if ($db_model) {
$new_model = $this->toArray(array_merge(array($key), $ignored_update_fields));
$update = array_diff($new_model, $db_model);
if (empty($update)) {
static::onNoUpdate();
} else {
dbUpdate($update, static::$table, "`$key`=?", array($this->$key));
static::onUpdate($this);
}
} else {
$new_model = $this->toArray(array($key));
$this->$key = dbInsert($new_model, static::$table);
if ($this->$key !== null) {
static::onCreate($this);
}
}
return $this->$key;
}
/**
* Fetch the sensor from the database.
* If it doesn't exist, returns null.
*
* @param array $unique_fields fields to search for an existing entry
* @return array|null
*/
protected function fetch($unique_fields = array())
{
$table = static::$table;
$key = static::$primaryKey;
if (isset($this->id)) {
return dbFetchRow(
"SELECT `$table` FROM ? WHERE `$key`=?",
array($this->$key)
);
}
$where = array();
$params = array();
foreach ($unique_fields as $field) {
if (isset($this->$field)) {
$where[] = " $field=?";
$params[] = $this->$field;
}
}
if (empty($params)) {
return null;
}
$row = dbFetchRow(
"SELECT * FROM `$table` WHERE " . implode(' AND', $where),
$params
);
$this->$key = $row[$key];
return $row;
}
/**
* Convert this Model to an array with fields that match the database
*
* @param array $exclude Exclude the listed fields
* @return array
*/
abstract public function toArray($exclude = array());
/**
* Returns if this model passes validation and should be saved to the database
*
* @return bool
*/
abstract public function isValid();
/**
* @param static $model
*/
public static function onDelete($model)
{
if (isCli()) {
echo '-';
}
}
/**
* @param static $model
*/
public static function onCreate($model)
{
if (isCli()) {
echo '+';
}
}
/**
* @param static $model
*/
public static function onUpdate($model)
{
if (isCli()) {
echo 'U';
}
}
public static function onNoUpdate()
{
if (isCli()) {
echo '.';
}
}
}