szurubooru/src/Models/AbstractCrudModel.php
Marcin Kurczewski b22e74c0e9 Closed #72
2014-02-05 08:35:24 +01:00

149 lines
3.2 KiB
PHP

<?php
abstract class AbstractCrudModel implements IModel
{
public static function spawn()
{
$entityClassName = static::getEntityClassName();
return new $entityClassName();
}
public static function remove($entities)
{
throw new NotImplementedException();
}
public static function save($entity)
{
throw new NotImplementedException();
}
public static function findById($key, $throw = true)
{
$query = (new SqlQuery)
->select('*')
->from(static::getTableName())
->where('id = ?')->put($key);
$row = Database::fetchOne($query);
if ($row)
return self::convertRow($row);
if ($throw)
throw new SimpleNotFoundException('Invalid ' . static::getTableName() . ' ID "' . $key . '"');
return null;
}
public static function findByIds(array $ids)
{
$query = (new SqlQuery)
->select('*')
->from(static::getTableName())
->where('id')->in()->genSlots($ids)->put($ids);
$rows = Database::fetchAll($query);
if ($rows)
return self::convertRows($rows);
return [];
}
public static function getCount()
{
$query = new SqlQuery();
$query->select('count(1)')->as('count')->from(static::getTableName());
return Database::fetchOne($query)['count'];
}
public static function getEntityClassName()
{
$modelClassName = get_called_class();
$entityClassName = str_replace('Model', 'Entity', $modelClassName);
return $entityClassName;
}
public static function convertRow($row)
{
$entity = self::spawn();
foreach ($row as $key => $val)
{
$key = TextHelper::snakeCaseToCamelCase($key, true);
$entity->$key = $val;
}
return $entity;
}
public static function convertRows(array $rows)
{
$keyCache = [];
$entities = [];
foreach ($rows as $i => $row)
{
$entity = self::spawn();
foreach ($row as $key => $val)
{
if (isset($keyCache[$key]))
$key = $keyCache[$key];
else
$key = $keyCache[$key] = TextHelper::snakeCaseToCamelCase($key, true);
$entity->$key = $val;
}
$entities[$i] = $entity;
}
return $entities;
}
public static function forgeId($entity)
{
$table = static::getTableName();
if (!Database::inTransaction())
throw new Exception('Can be run only within transaction');
if (!$entity->id)
{
$config = \Chibi\Registry::getConfig();
$query = (new SqlQuery);
if ($config->main->dbDriver == 'sqlite')
$query->insertInto($table)->defaultValues();
else
$query->insertInto($table)->values()->open()->close();
Database::query($query);
$entity->id = Database::lastInsertId();
}
}
public static function preloadOneToMany($entities,
$foreignEntityLocalSelector,
$foreignEntityForeignSelector,
$foreignEntityProcessor,
$foreignEntitySetter)
{
if (empty($entities))
return;
$foreignIds = [];
$entityMap = [];
foreach ($entities as $entity)
{
$foreignId = $foreignEntityLocalSelector($entity);
if (!isset($entityMap[$foreignId]))
$entityMap[$foreignId] = [];
$entityMap[$foreignId] []= $entity;
$foreignIds []= $foreignId;
}
$foreignEntities = $foreignEntityProcessor($foreignIds);
foreach ($foreignEntities as $foreignEntity)
{
$key = $foreignEntityForeignSelector($foreignEntity);
foreach ($entityMap[$key] as $entity)
$foreignEntitySetter($entity, $foreignEntity);
}
}
}