1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-08-13 22:12:50 +02:00

more changes

This commit is contained in:
Laurent Cozic
2016-10-26 16:03:26 +01:00
parent 581f188927
commit 4dfb8d0c39
6 changed files with 176 additions and 23 deletions

View File

@@ -113,24 +113,8 @@ abstract class ApiController extends Controller {
} }
} }
static private function serializeResponse($data) {
$output = $data;
if ($output instanceof Collection) $output = $output->all();
if ($output instanceof BaseModel) {
$output = $output->toPublicArray();
} else if (is_array($output)) {
foreach ($output as $k => $v) {
$output[$k] = self::serializeResponse($v);
}
}
return $output;
}
static protected function successResponse($data = null) { static protected function successResponse($data = null) {
$output = self::serializeResponse($data); $output = BaseModel::anythingToPublicArray($data);
return new JsonResponse($output); return new JsonResponse($output);
} }

View File

@@ -4,6 +4,7 @@ namespace AppBundle\Model;
use \Illuminate\Database\Eloquent\Model; use \Illuminate\Database\Eloquent\Model;
use \Illuminate\Support\Facades\DB; use \Illuminate\Support\Facades\DB;
use \Illuminate\Database\Eloquent\Collection;
class BaseModel extends \Illuminate\Database\Eloquent\Model { class BaseModel extends \Illuminate\Database\Eloquent\Model {
@@ -39,6 +40,92 @@ class BaseModel extends \Illuminate\Database\Eloquent\Model {
return self::$clientId; return self::$clientId;
} }
static public function anythingToAsciiTable($data, $fields = null) {
$data = self::anythingToPublicArray($data);
if (!count($data)) return '';
$header = array();
$r = $data[0];
foreach ($r as $k => $v) {
$header[] = $k;
}
$lengths = array();
foreach ($header as $f) {
$lengths[$f] = max(strlen($f), self::fieldMaxLength($f, $data));
}
if (!$fields) {
$fields = $header;
} else {
$header = $fields;
}
$rows = array();
$dividers = array();
$row = array();
foreach ($header as $k) {
$row[] = str_pad($k, $lengths[$k]);
}
$rows[] = $row;
$dividers[] = ' | ';
$row = array();
foreach ($header as $k) {
$row[] = str_repeat('-', $lengths[$k]);
}
$rows[] = $row;
$dividers[] = '-|-';
foreach ($data as $r) {
$row = array();
foreach ($r as $k => $v) {
if (!in_array($k, $fields)) continue;
$row[$k] = str_pad($v, $lengths[$k]);
}
$rows[] = $row;
$dividers[] = ' | ';
}
$i = 0;
$output = '';
foreach ($rows as $row) {
$line = '';
foreach ($row as $v) {
if ($line != '') $line .= $dividers[$i];
$line .= $v;
}
$output .= $line . "\n";
$i++;
}
return $output;
}
static private function fieldMaxLength($field, $data) {
$s = 0;
foreach ($data as $row) {
$s = max(strlen($row[$field]), $s);
}
return $s;
}
static public function anythingToPublicArray($data) {
$output = $data;
if ($output instanceof Collection) $output = $output->all();
if ($output instanceof BaseModel) {
$output = $output->toPublicArray();
} else if (is_array($output)) {
foreach ($output as $k => $v) {
$output[$k] = self::anythingToPublicArray($v);
}
}
return $output;
}
public function fromPublicArray($array) { public function fromPublicArray($array) {
foreach ($array as $k => $v) { foreach ($array as $k => $v) {
if ($k == 'rev_id') { if ($k == 'rev_id') {

View File

@@ -11,19 +11,58 @@ class Change extends BaseModel {
); );
static public function changesDoneAfterId($userId, $clientId, $changeId) { static public function changesDoneAfterId($userId, $clientId, $changeId) {
// Simplification:
//
// - If create, update, delete => return nothing
// - If create, update => return last, and set type as 'create'
// - If update, update, delete, update => return 'delete' only
// - If update, update, update => return last
$limit = 100; $limit = 100;
$items = self::where('id', '>', $changeId) $changes = self::where('id', '>', $changeId)
->where('user_id', '=', $userId) ->where('user_id', '=', $userId)
->where('client_id', '!=', $clientId) ->where('client_id', '!=', $clientId)
->orderBy('id') ->orderBy('id')
->limit($limit + 1) ->limit($limit + 1)
->get(); ->get();
$hasMore = $limit < count($items);
if ($hasMore) array_pop($items); $hasMore = $limit < count($changes);
if ($hasMore) array_pop($changes);
$itemIdToChange = array();
$createdItems = array();
$deletedItems = array();
foreach ($changes as $change) {
if ($change->type == Change::enumId('type', 'create')) {
$createdItems[] = $change->item_id;
} else if ($change->type == Change::enumId('type', 'delete')) {
$deletedItems[] = $change->item_id;
}
$itemIdToChange[$change->item_id] = $change;
}
$output = array();
foreach ($itemIdToChange as $itemId => $change) {
if (in_array($itemId, $createdItems) && in_array($itemId, $deletedItems)) {
// Item both created then deleted - skip
continue;
}
if (in_array($itemId, $deletedItems)) {
// Item was deleted at some point - just return one 'delete' event
$change->type = Change::enumId('type', 'delete');
} else if (in_array($itemId, $createdItems)) {
// Item was created then updated - just return one 'create' event with the latest changes
$change->type = Change::enumId('type', 'create');
}
$output[] = $change;
}
return array( return array(
'has_more' => $hasMore, 'has_more' => $hasMore,
'items' => $items, 'items' => $output,
); );
} }

View File

@@ -26,8 +26,12 @@ class BaseTestCase extends TestCase {
return $this->createModelId('client', $num); return $this->createModelId('client', $num);
} }
protected function userId($num = 1) {
return $this->createModelId('user', $num);
}
protected function user($num = 1) { protected function user($num = 1) {
$id = $this->createModelId('user', $num); $id = $this->userId($num);
$user = User::find($id); $user = User::find($id);
if ($user) return $user; if ($user) return $user;

View File

@@ -128,5 +128,44 @@ class ChangeTest extends BaseTestCase {
$d = $n->toPublicArray(); $d = $n->toPublicArray();
$this->assertEquals(2, $d['rev_id']); $this->assertEquals(2, $d['rev_id']);
} }
public function testListChanges() {
$n1 = new Note();
$n1->fromPublicArray(array('body' => 'test'));
$n1->owner_id = $this->userId();
$n1->save();
$n1->fromPublicArray(array('body' => 'test change'));
$n1->save();
$r = Change::changesDoneAfterId($this->userId(), $this->clientId(1), 0);
$this->assertCount(2, $r);
$this->assertFalse($r['has_more']);
$this->assertCount(0, $r['items']); // Since client 1 is the one that made the changes, no sync data needs to be returned
$r = Change::changesDoneAfterId($this->userId(), $this->clientId(2), 0);
$this->assertCount(1, $r['items']);
$n2 = new Note();
$n2->fromPublicArray(array('body' => 'second note'));
$n2->owner_id = $this->userId();
$n2->save();
$r = Change::changesDoneAfterId($this->userId(), $this->clientId(2), 0);
$this->assertCount(2, $r['items']);
$r = Change::changesDoneAfterId($this->userId(), $this->clientId(2), $r['items'][0]['id']);
$this->assertCount(1, $r['items']);
$n1->delete();
$r = Change::changesDoneAfterId($this->userId(), $this->clientId(2), 0);
$this->assertCount(1, $r['items']);
}
} }

View File

@@ -16,7 +16,7 @@ $capsule = new \Illuminate\Database\Capsule\Manager();
$capsule->addConnection([ $capsule->addConnection([
'driver' => 'mysql', 'driver' => 'mysql',
'host' => 'localhost', 'host' => 'localhost',
'database' => 'notes_test', 'database' => $dbName,
'username' => 'root', 'username' => 'root',
'password' => 'pass', 'password' => 'pass',
'charset' => 'utf8', 'charset' => 'utf8',