diff --git a/app/config/services.yml b/app/config/services.yml index f4fadc0ccd..9b83891b33 100755 --- a/app/config/services.yml +++ b/app/config/services.yml @@ -7,8 +7,7 @@ services: app.eloquent: class: AppBundle\Eloquent - # arguments: [%kernel.environment%, '@app.mime_types', '@app.paths'] - arguments: [%database%, '@app.mime_types', '@app.paths'] + arguments: [%database%, '@app.mime_types', '@app.paths', '@app.cache'] twig.exception_listener: class: stdObject @@ -20,3 +19,7 @@ services: app.mime_types: class: AppBundle\MimeTypes arguments: ['@app.paths'] + + app.cache: + class: AppBundle\Cache + arguments: [%kernel.cache_dir%] diff --git a/src/AppBundle/Cache.php b/src/AppBundle/Cache.php new file mode 100755 index 0000000000..97356d317b --- /dev/null +++ b/src/AppBundle/Cache.php @@ -0,0 +1,48 @@ +cacheDir_ = $kernelCacheDir . '/cache_service'; + if (!file_exists($this->cacheDir_)) mkdir($this->cacheDir_, 0755, true); + } + + private function adapter() { + if (!$this->adapter_) $this->adapter_ = new FilesystemAdapter('', 0, $this->cacheDir_); + return $this->adapter_; + } + + public function get($k) { + $item = $this->adapter()->getItem($k); + return $item->isHit() ? json_decode($item->get(), true) : null; + } + + public function set($k, $v, $expiryTime = null) { + $item = $this->adapter()->getItem($k); + $item->set(json_encode($v)); + if ($expiryTime) $item->expiresAfter($expiryTime); + $this->adapter()->save($item); + return $item; + } + + public function delete($k) { + return $this->adapter()->deleteItem($k); + } + + public function getOrSet($k, $func, $expiryTime = null) { + $v = $this->get($k); + if ($v === null) { + $v = $func(); + $this->set($k, $v, $expiryTime); + } + return $v; + } + +} \ No newline at end of file diff --git a/src/AppBundle/Controller/FoldersController.php b/src/AppBundle/Controller/FoldersController.php index ca179deb1f..333e31fb45 100755 --- a/src/AppBundle/Controller/FoldersController.php +++ b/src/AppBundle/Controller/FoldersController.php @@ -8,6 +8,10 @@ use Symfony\Component\HttpFoundation\Request; use AppBundle\Controller\ApiController; use AppBundle\Model\Folder; + + +use AppBundle\Model\BaseItem; + class FoldersController extends ApiController { /** @@ -33,7 +37,7 @@ class FoldersController extends ApiController { * @Route("/folders/{id}") */ public function oneAction($id, Request $request) { - $folder = Folder::find(Folder::unhex($id)); + $folder = Folder::byId(Folder::unhex($id)); if (!$folder && !$request->isMethod('PUT')) return static::errorResponse('Not found', 0, 404); if ($request->isMethod('GET')) { @@ -68,7 +72,7 @@ class FoldersController extends ApiController { * @Route("/folders/{id}/notes") */ public function linkAction($id, Request $request) { - $folder = Folder::find(Folder::unhex($id)); + $folder = Folder::byId(Folder::unhex($id)); if (!$folder) return static::errorResponse('Not found', 0, 404); if ($request->isMethod('GET')) { diff --git a/src/AppBundle/Eloquent.php b/src/AppBundle/Eloquent.php index 84569098a9..ac0ac0d721 100755 --- a/src/AppBundle/Eloquent.php +++ b/src/AppBundle/Eloquent.php @@ -6,7 +6,7 @@ class Eloquent { private $capsule_ = null; - public function __construct($dbParams, $mimeTypes, $paths) { + public function __construct($dbParams, $mimeTypes, $paths, $cache) { $this->capsule_ = new \Illuminate\Database\Capsule\Manager(); $dbParamsDefaults = array( @@ -23,8 +23,9 @@ class Eloquent { // In order to keep things lightweight, the models aren't part of Symfony dependency // injection framework, so any service required by a model needs to be injected here. - Model\File::$mimeTypes = $mimeTypes; - Model\File::$paths = $paths; + Model\File::$mimeTypes_ = $mimeTypes; + Model\File::$paths_ = $paths; + Model\BaseModel::$cache_ = $cache; } public function connection() { diff --git a/src/AppBundle/Model/BaseItem.php b/src/AppBundle/Model/BaseItem.php index a88d399fc7..3a04a53ba0 100755 --- a/src/AppBundle/Model/BaseItem.php +++ b/src/AppBundle/Model/BaseItem.php @@ -30,13 +30,13 @@ class BaseItem extends BaseModel { return self::enumId('type', $typeName); } - static public function byId($itemTypeId, $itemId) { + static public function byTypeAndId($itemTypeId, $itemId) { if ($itemTypeId == BaseItem::enumId('type', 'folder')) { - return Folder::where('id', '=', $itemId)->first(); + return Folder::find($itemId); } else if ($itemTypeId == BaseItem::enumId('type', 'note')) { - return Note::where('id', '=', $itemId)->first(); + return Note::find($itemId); } else if ($itemTypeId == BaseItem::enumId('type', 'tag')) { - return Tag::where('id', '=', $itemId)->first(); + return Tag::find($itemId); } throw new \Exception('Unsupported item type: ' . $itemTypeId); diff --git a/src/AppBundle/Model/BaseModel.php b/src/AppBundle/Model/BaseModel.php index b1ea9b9126..095162872f 100755 --- a/src/AppBundle/Model/BaseModel.php +++ b/src/AppBundle/Model/BaseModel.php @@ -8,6 +8,8 @@ use \Illuminate\Database\Eloquent\Collection; class BaseModel extends \Illuminate\Database\Eloquent\Model { + static public $cache_ = null; + public $timestamps = false; public $useUuid = false; @@ -41,6 +43,10 @@ class BaseModel extends \Illuminate\Database\Eloquent\Model { parent::__construct($attributes); } + static protected function cache() { + return self::$cache_; + } + static public function setClientId($clientId) { self::$clientId = $clientId; } @@ -171,23 +177,56 @@ class BaseModel extends \Illuminate\Database\Eloquent\Model { $output['item_type'] = BaseItem::enumName('type', $output['item_type'], true); } - $maxRevId = 0; foreach ($this->diffableFields as $field) { - $r = $this->diffableField($field, true); - $output[$field] = $r['text']; - $maxRevId = max($maxRevId, $r['revId']); + $output[$field] = $this->diffableField($field); } - $output['rev_id'] = $maxRevId; - return $output; } - public function diffableField($fieldName, $returnRevId = false) { - return Change::fullFieldText($this->id, $fieldName, null, $returnRevId); + public function idString() { + return $this->useUuid ? self::hex($this->id) : (string)$this->id; + } + + // private function cachePrefix() { + // return 'Model.' . $this->classItemTypeName() . '.' . $this->idString(); + // } + + // public function cacheSet($key, $value) { + // return self::cache()->set($this->cachePrefix() . '.' . $key, $value); + // } + + // public function cacheGet($key) { + // return self::cache()->get($this->cachePrefix() . '.' . $key); + // } + + // public function cacheDelete($key) { + // self::cache()->delete($this->cachePrefix() . '.' . $key); + // } + + // public function cacheGetOrSet($key, $func, $expiryTime = null) { + // return self::cache()->getOrSet($this->cachePrefix() . '.' . $key, $func, $expiryTime); + // } + + // public function cacheClear() { + // $p = $this->cachePrefix(); + // $this->cacheDelete('diffableField.title'); + // $this->cacheDelete('diffableField.body'); + // } + + public function diffableField($fieldName) { + return Change::fullFieldText($this->id, $fieldName); + + // $r = $this->cacheGet('diffableField.' . $fieldName); + // if ($r !== null) return $r . '*'; + + // $r = Change::fullFieldText($this->id, $fieldName); + // $this->cacheSet('diffableField.' . $fieldName, $r); + // return $r; } public function setDiffableField($fieldName, $fieldValue) { + //$this->cacheDelete('diffableField.' . $fieldName); $this->changedDiffableFields[$fieldName] = $fieldValue; } @@ -336,6 +375,8 @@ class BaseModel extends \Illuminate\Database\Eloquent\Model { $output = parent::save($options); + //$this->cacheClear(); + $this->isNew = null; if ($this->isVersioned) { @@ -349,6 +390,8 @@ class BaseModel extends \Illuminate\Database\Eloquent\Model { } public function delete() { + //$this->cacheClear(); + $output = parent::delete(); if (count($this->isVersioned)) { @@ -399,4 +442,13 @@ class BaseModel extends \Illuminate\Database\Eloquent\Model { return $change; } + static public function byId($id) { + $Class = get_called_class(); + return $Class::find($id); + // $Class = get_called_class(); + // return $this->getOrSet($Class.$id, function() use($Class, $id) { + // return $Class::find($id); + // }); + } + } diff --git a/src/AppBundle/Model/Change.php b/src/AppBundle/Model/Change.php index 0d45fc05b4..b849ecff1c 100755 --- a/src/AppBundle/Model/Change.php +++ b/src/AppBundle/Model/Change.php @@ -20,11 +20,11 @@ class Change extends BaseModel { $limit = 100; $changes = self::where('id', '>', $fromChangeId) - ->where('user_id', '=', $userId) - ->where('client_id', '!=', $clientId) - ->orderBy('id') - ->limit($limit + 1) - ->get(); + ->where('user_id', '=', $userId) + ->where('client_id', '!=', $clientId) + ->orderBy('id') + ->limit($limit + 1) + ->get(); $hasMore = $limit < count($changes); if ($hasMore) array_pop($changes); @@ -104,7 +104,7 @@ class Change extends BaseModel { } static private function requireItemById($itemTypeId, $itemId) { - $item = BaseItem::byId($itemTypeId, $itemId); + $item = BaseItem::byTypeAndId($itemTypeId, $itemId); if (!$item) throw new \Exception('No such item: ' . $itemTypeId . ' ' . $itemId); return $item; } @@ -117,10 +117,9 @@ class Change extends BaseModel { return $query->get(); } - static public function fullFieldText($itemId, $itemField, $toId = null, $returnRevId = false) { + static public function fullFieldText($itemId, $itemField, $toId = null) { $output = ''; $changes = self::itemFieldHistory($itemId, $itemField, $toId); - $revId = 0; for ($i = 0; $i < count($changes); $i++) { $change = $changes[$i]; if (!empty($change->delta)) { @@ -131,11 +130,9 @@ class Change extends BaseModel { } $output = $result[0]; } - - $revId = $change->id; } - return $returnRevId ? array('text' => $output, 'revId' => $revId) : $output; + return $output; } public function createDelta($newText) { diff --git a/src/AppBundle/Model/File.php b/src/AppBundle/Model/File.php index b9c2b30690..15382b280a 100755 --- a/src/AppBundle/Model/File.php +++ b/src/AppBundle/Model/File.php @@ -4,8 +4,8 @@ namespace AppBundle\Model; class File extends BaseModel { - static public $mimeTypes = null; - static public $paths = null; + static public $mimeTypes_ = null; + static public $paths_ = null; public $useUuid = true; public $incrementing = false; diff --git a/src/AppBundle/Model/Tag.php b/src/AppBundle/Model/Tag.php index 7abcc2f024..f0f0ddfe66 100755 --- a/src/AppBundle/Model/Tag.php +++ b/src/AppBundle/Model/Tag.php @@ -69,7 +69,7 @@ class Tag extends BaseItem { $output = array(); $taggedItems = Tagged_item::where('tag_id', '=', $this->id)->get(); foreach ($taggedItems as $taggedItem) { - $item = BaseItem::byId($taggedItem->item_type, $taggedItem->item_id); + $item = BaseItem::byTypeAndId($taggedItem->item_type, $taggedItem->item_id); $output[] = $item; } return $output; diff --git a/tests/Model/ChangeTest.php b/tests/Model/ChangeTest.php index 85b43ac06d..1601c0d469 100755 --- a/tests/Model/ChangeTest.php +++ b/tests/Model/ChangeTest.php @@ -127,25 +127,6 @@ class ChangeTest extends BaseTestCase { $this->assertEquals($r, 'cd CLIENT1 efgh ijkl FROMCLIENT2'); } - public function testRevId() { - $n = new Note(); - $n->setDiffableField('body', 'abcd efgh'); - $n->save(); - - $noteId = $n->id; - - $n = Note::find($noteId); - $d = $n->toPublicArray(); - $this->assertEquals(1, $d['rev_id']); - - $n->setDiffableField('body', '123456'); - $n->save(); - - $n = Note::find($noteId); - $d = $n->toPublicArray(); - $this->assertEquals(2, $d['rev_id']); - } - public function testListChanges() { $n1 = new Note(); $n1->fromPublicArray(array('body' => 'test')); diff --git a/tests/Model/NoteTest.php b/tests/Model/NoteTest.php index 7dc82f1015..7df8f2f172 100755 --- a/tests/Model/NoteTest.php +++ b/tests/Model/NoteTest.php @@ -36,7 +36,6 @@ class NoteTest extends BaseTestCase { $this->assertEquals('the title', $b['title']); $this->assertEquals('the body', $b['body']); - $this->assertArrayHasKey('rev_id', $b); } } \ No newline at end of file