Commit 7c678678 authored by Matthieu Le Corre's avatar Matthieu Le Corre

working DB engine

Signed-off-by: default avatarroot <root@uncloud-tools.univ-nantes.prive>
parent b2ff4e29
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
<?php
/**
* @author 2020 Matthieu Le Corre <matthieu.lecorre@univ-nantes.fr>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\whiteboard\Collaboration ;
use OCP\ICache ;
use OCP\ICacheFactory;
use OCA\whiteboard\Db\Step ;
use OCA\whiteboard\Db\StepMapper ;
use OCA\whiteboard\Db\User ;
use OCA\whiteboard\Db\UserMapper ;
//class CollaborationEngine implements ICollaborationEngine {
class CollaborationEngine {
private $StepMapper ;
private $UserMapper ;
private $cache ;
public function __construct(ICacheFactory $cacheFactory, StepMapper $StepMapper, UserMapper $UserMapper) {
$this->StepMapper = $StepMapper ;
$this->UserMapper = $UserMapper ;
$this->AppName = "whiteboard";
//$this->cache = $cacheFactory->createDistributed('WhiteboardSession::'.$this->file);
}
//DONE
public function startSession(int $fileId) {
// nothing to setup with DB engine
}
//DONE
public function addUser(int $fileId, string $user) {
$usr = $this->UserMapper->find($user,$this->AppName,$fileId) ;
if (! $usr) {
$Nuser = new User() ;
$Nuser->setAppId($this->AppName) ;
$Nuser->setUserId($user) ;
$Nuser->setLastSeen(time()) ;
$Nuser->setFileId($fileId) ;
return $this->UserMapper->insert($Nuser);
} else {
return "already there" ;
} ;
}
//ALMOST DONE
public function removeUser(int $fileId, string $user) {
$usr = $this->UserMapper->find($user,$this->AppName,$fileId) ;
$cnt = count($this->UserMapper->findAll($this->AppName,$fileId)) ;
if ($usr) {
$this->UserMapper->delete($usr) ;
}
$cnt = count($this->UserMapper->findAll($this->AppName,$fileId)) ;
if ( $cnt == 0 ) {
// delete all steps for this file
}
return "user removed" ;
}
// ALMOST DONE
public function addStep(int $fileId,string $user, string $type, string $datas) {
$Nstep = new Step() ;
$Nstep->setAppId($this->AppName) ;
$Nstep->setUserId($user) ;
$Nstep->setStepId(time()) ;
$Nstep->setFileId($fileId) ;
$Nstep->setStepForwarded($user) ;
$Nstep->setStepType($type) ;
$Nstep->setStepData($datas) ;
return $this->StepMapper->insert($Nstep);
}
// DONE
public function getSteps($fileId) {
return $this->StepMapper->findAll($this->AppName,$fileId) ;
}
// DONE
public function getUserList($fileId) {
return $this->UserMapper->findAll($this->AppName,$fileId) ;
}
// DONE
public function waitForNewSteps(int $fileId, string $user){
$timeout = 20 ;
$elapsedTime = 0;
while (empty($steps) && $elapsedTime < $timeout) {
$steps = $this->StepMapper->findLasts($this->AppName,$fileId,$user) ;
$elapsedTime++ ;
if (empty($steps)) {
sleep(1) ;
}
} ;
foreach ($steps as $step) {
$forwarded = explode(',',$step->getStepForwarded()) ;
$forwarded[] = $user ;
$result = implode(',',$forwarded) ;
$step->setStepForwarded($result) ;
$this->StepMapper->update($step) ;
} ;
return $steps ;
}
}
\ No newline at end of file
......@@ -109,6 +109,7 @@ class SimpleFileCollaborationEngine {
//$step = json_decode($this->cache->get('WhiteboardSession::'.$this->file)) ;
$step = $this->getLastStep() ;
$elapsedTime++ ;
return $step ;
} ;
//remove key from cache
//$this->cache.remove('WhiteboardSession::'.$this->file) ;
......@@ -118,7 +119,9 @@ class SimpleFileCollaborationEngine {
/* Private methods */
private function updateStorage() {
return file_put_contents("/tmp/session-".$this->file,json_encode($this->Fsession), LOCK_EX) ;
$payload = json_encode($this->Fsession) ;
$result = file_put_contents("/tmp/session-".$this->file,$payload) ;
return $result ;
}
private function getUserNumber() {
......@@ -130,14 +133,15 @@ class SimpleFileCollaborationEngine {
}
private function setLastStep($step){
file_put_contents("/tmp/session-queue-".$this->file,json_encode($step),FILE_APPEND | LOCK_EX) ;
$jstep = json_encode($step) ;
file_put_contents("/tmp/session-queue-".$this->file,jstep,FILE_APPEND) ;
}
private function getLastStep(){
$steps = file_get_contents("/tmp/session-queue".$this->file) ;
$step = file_get_contents("/tmp/session-queue-".$this->file) ;
return json_decode($steps,true) ;
return json_decode($step,true) ;
}
......
......@@ -22,25 +22,24 @@
namespace OCA\whiteboard\Controller ;
use OCP\AppFramework\Controller ;
use OCP\IRequest;
use OCP\Files\File;
use OCP\Files\Folder;
use OCP\IRequest;;
use OCP\User ;
use OCP\ICache ;
use OCP\ICacheFactory;
use OCA\whiteboard\Collaboration\SimpleFileCollaborationEngine ;
use OCA\whiteboard\Collaboration\CollaborationEngine ;
class CollaborationController extends Controller {
/**
* @NoAdminRequired
*
**/
public function __construct($AppName, IRequest $request, Folder $userFolder ,ICacheFactory $cacheFactory ) {
public function __construct($AppName,IRequest $request,ICacheFactory $cacheFactory, CollaborationEngine $engine) {
parent::__construct($AppName, $request);
$this->id = $request->getParam("id") ;
//$this->id = $request->getParam("id") ;
$this->engine = new SimpleFileCollaborationEngine($this->id,$cacheFactory) ;
$this->engine = $engine ;
}
......@@ -57,7 +56,7 @@ class CollaborationController extends Controller {
*
**/
public function addUser($id,$user) {
return $this->engine->addUser($user) ;
return $this->engine->addUser($id,$user) ;
}
/**
......@@ -65,7 +64,7 @@ class CollaborationController extends Controller {
*
**/
public function removeUser($id,$user) {
return $this->engine->removeUser($user) ;
return $this->engine->removeUser($id,$user) ;
}
/**
......@@ -79,24 +78,29 @@ class CollaborationController extends Controller {
/**
* @NoAdminRequired
*
* @param int $id
* @param string $user
* @param string $type
* @param string $step
*
**/
public function addStep($id,$user,$type,$step) {
return $this->engine->addStep($user,$type,$step) ;
public function addStep(int $id,string $user,string $type, string $step) {
return $this->engine->addStep($id,$user,$type,$step) ;
}
/**
* @NoAdminRequired
*
**/
public function getSteps($id,$from,$handlecheckpoint) {
return $this->engine->getSteps($from,$handlecheckpoint) ;
public function getSteps($id) {
return $this->engine->getSteps($id) ;
}
/**
* @NoAdminRequired
*
**/
public function pushStep($id) {
return $this->engine->waitForNewSteps() ;
public function pushStep(int $id,string $user) {
return $this->engine->waitForNewSteps($id,$user) ;
}
}
\ No newline at end of file
<?php
/**
* @author 2019 Matthieu Le Corre <matthieu.lecorre@univ-nantes.fr>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\whiteboard\Db ;
use JsonSerializable;
use OCP\AppFramework\Db\Entity;
class Step extends Entity implements JsonSerializable {
protected $appId;
protected $userId;
protected $stepId;
protected $stepType;
protected $stepForwarded;
protected $stepData;
protected $fileId ;
public function __construct() {
$this->addType("id",integer) ;
$this->addType("appId",string) ;
$this->addType("userId",string) ;
$this->addType("fileId",integer) ;
$this->addType("stepId",integer) ;
$this->addType("stepType",string) ;
$this->addType("stepData",string) ;
$this->addType("stepForwarded",string) ;
}
public function jsonSerialize() {
return [
'id' => $this->id,
'appId' => $this->appId,
'userId' => $this->userId,
'fileId' => $this->fileId,
'stepData' => $this->stepData,
'stepId'=> $this->stepId,
'stepType' => $this->stepType,
'stepForwarded' => $this->stepForwarded
];
}
}
<?php
/**
* @author 2019 Matthieu Le Corre <matthieu.lecorre@univ-nantes.fr>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\whiteboard\Db ;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Db\QBMapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCA\whiteboard\Db\Step ;
Class StepMapper extends QBMApper {
public function __construct(IDBConnection $db) {
parent::__construct($db, 'cengine_steps', Step::class) ;
}
public function findLasts(string $app_id, int $file_id, string $user_id) {
$qb = $this->db->getQueryBuilder();
$qb->select('*')
->from($this->getTableName())
->where(
$qb->expr()->eq('app_id', $qb->createNamedParameter($app_id, IQueryBuilder::PARAM_STR))
)->andWhere(
$qb->expr()->eq('file_id', $qb->createNamedParameter($file_id, IQueryBuilder::PARAM_INT))
)->andWhere(
$qb->expr()->neq('step_type',$qb->createNamedParameter('save', IQueryBuilder::PARAM_STR))
)->andWhere(
$qb->expr()->notlike('step_forwarded', $qb->createNamedParameter('%' . $this->db->escapeLikeParameter($user_id) . '%'))
)->orWhere(
$qb->expr()->isNull('step_forwarded')
)
->orderBy('step_id', 'ASC') ;
return $this->findEntities($qb) ;
}
public function findAll(string $app_id, int $file_id) {
$qb = $this->db->getQueryBuilder();
$sub = $this->db->getQueryBuilder() ;
$sub->select('step_id')
->from($this->getTableName())
->Where(
$sub->expr()->eq('step_type',$sub->createNamedParameter('save', IQueryBuilder::PARAM_STR))
)
->orderBy('step_id','DESC')
->setMaxResults(1) ;
$lastSave = $this->findEntities($sub) ;
$qb->select('*')
->from($this->getTableName())
->Where(
$qb->expr()->eq('app_id', $qb->createNamedParameter($app_id, IQueryBuilder::PARAM_STR))
)->andWhere(
$qb->expr()->eq('file_id', $qb->createNamedParameter($file_id, IQueryBuilder::PARAM_INT))
);
if (count($lastSave) != 0) {
$qb->andWhere(
$qb->expr()->gt('step_id',$qb->createNamedParameter($lastSave->getSteptId, IQueryBuilder::PARAM_INT))
);
} ;
$qb->orderBy('step_id','DESC') ;
return $this->findEntities($qb) ;
}
}
\ No newline at end of file
<?php
/**
* @author 2020 Matthieu Le Corre <matthieu.lecorre@univ-nantes.fr>
* @author 2019 Matthieu Le Corre <matthieu.lecorre@univ-nantes.fr>
*
* @license GNU AGPL version 3 or any later version
*
......@@ -19,21 +19,35 @@
*
*/
use OCP\EventDispatcher\Event;
namespace OCA\whiteboard\Db ;
namespace OCA\whiteboard\Collaboration ;
use JsonSerializable;
class stepEvent extends Event {
use OCP\AppFramework\Db\Entity;
private $step ;
class User extends Entity implements JsonSerializable {
public function __construct(Array $step) {
parent::__construct() ;
protected $appId;
protected $userId;
protected $fileId;
protected $lastSeen;
$this->step = $step ;
public function __construct() {
$this->addType("id",integer) ;
$this->addType("appId",string) ;
$this->addType("userId",string) ;
$this->addType("fileId",integer) ;
$this->addType("lastSeen",integer) ;
}
public function getStep(): Array {
return $this->step ;
public function jsonSerialize() {
return [
'id' => $this->id,
'appId' => $this->appId,
'userId' => $this->userId,
'fileId'=> $this->fileId,
'lastSeen' => $this->lastSeen
];
}
}
<?php
/**
* @author 2019 Matthieu Le Corre <matthieu.lecorre@univ-nantes.fr>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\whiteboard\Db ;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Db\QBMapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCA\whiteboard\Db\User ;
Class UserMapper extends QBMApper {
public function __construct(IDBConnection $db) {
parent::__construct($db, 'cengine_users', User::class) ;
}
public function find(string $user_id, string $app_id, int $file_id) {
$qb = $this->db->getQueryBuilder();
$qb->select('*')
->from($this->getTableName())
->where(
$qb->expr()->eq('user_id', $qb->createNamedParameter($user_id, IQueryBuilder::PARAM_STR))
)->andWhere(
$qb->expr()->eq('app_id', $qb->createNamedParameter($app_id, IQueryBuilder::PARAM_STR))
)->andWhere(
$qb->expr()->eq('file_id', $qb->createNamedParameter($file_id, IQueryBuilder::PARAM_INT))
);
try {
return $this->findEntity($qb) ;
}
catch (DoesNotExistException $e ) {
return null ;
}
}
public function findAll(string $app_id, int $file_id) {
$qb = $this->db->getQueryBuilder();
$qb->select('*')
->from($this->getTableName())
->Where(
$qb->expr()->eq('app_id', $qb->createNamedParameter($app_id, IQueryBuilder::PARAM_STR))
)->andWhere(
$qb->expr()->eq('file_id', $qb->createNamedParameter($file_id, IQueryBuilder::PARAM_INT))
);
return $this->findEntities($qb) ;
}
}
\ No newline at end of file
<?php
/**
* @author 2019 Matthieu Le Corre <matthieu.lecorre@univ-nantes.fr>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\whiteboard\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\SimpleMigrationStep;
use OCP\Migration\IOutput;
class Version000001Date20200416 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
// Session
if (!$schema->hasTable('cengine_steps')) {
$table = $schema->createTable('cengine_steps');
$table->addColumn('id', 'integer', [
'autoincrement' => true,
'notnull' => true,
]);
$table->addColumn('app_id', 'string', [
'notnull' => true,
'length' => 200
]);
$table->addColumn('user_id', 'string', [
'notnull' => true,
'length' => 200,
]);
$table->addColumn('file_id', 'integer', [
'notnull' => true,
]);
$table->addColumn('step_data', 'text', [
'notnull' => true,
'default' => ''
]);
$table->addColumn('step_id', 'bigint', [
'notnull' => true,
'unsigned'=> true
]);
$table->addColumn('step_forwarded', 'text', [
'notnull' => false,
]);
$table->addColumn('step_type', 'string', [
'notnull' => true,
'length' => 200
]);
$table->setPrimaryKey(['id']);