show some statistics on the index page
[grauphel.git] / lib / notestorage.php
1 <?php
2 /**
3  * Part of grauphel
4  *
5  * PHP version 5
6  *
7  * @category  Tools
8  * @package   Grauphel
9  * @author    Christian Weiske <cweiske@cweiske.de>
10  * @copyright 2014 Christian Weiske
11  * @license   http://www.gnu.org/licenses/agpl.html GNU AGPL v3
12  * @link      http://cweiske.de/grauphel.htm
13  */
14 namespace OCA\Grauphel\Lib;
15
16 /**
17  * Flat file storage for notes
18  *
19  * @category  Tools
20  * @package   Grauphel
21  * @author    Christian Weiske <cweiske@cweiske.de>
22  * @copyright 2014 Christian Weiske
23  * @license   http://www.gnu.org/licenses/agpl.html GNU AGPL v3
24  * @version   Release: @package_version@
25  * @link      http://cweiske.de/grauphel.htm
26  */
27 class NoteStorage
28 {
29     protected $urlGen;
30
31     public function __construct($urlGen)
32     {
33         $this->urlGen = $urlGen;
34     }
35     /**
36      * Create a new sync data object for fresh users.
37      * Used by loadSyncData()
38      *
39      * @param string $username User name
40      *
41      * @return SyncData New synchronization statistics
42      */
43     protected function getNewSyncData($username)
44     {
45         $syncdata = new SyncData();
46         $syncdata->initNew($username);
47         return $syncdata;
48     }
49
50     /**
51      * Updates the given $note object with data from $noteUpdate.
52      * Sets the last-sync-revision to $syncRevision
53      *
54      * @param object  $note         Original note object
55      * @param object  $noteUpdate   Update note object from a PUT to the API
56      * @param integer $syncRevision Current sync revision number
57      *
58      * @return void
59      */
60     public function update($note, $noteUpdate, $syncRevision)
61     {
62         static $updateFields = array(
63             'create-date',
64             'last-change-date',
65             'last-metadata-change-date',
66             'note-content',
67             'note-content-version',
68             'open-on-startup',
69             'pinned',
70             'tags',
71             'title',
72         );
73
74         $changed = array();
75         foreach ($updateFields as $field) {
76             $changed[$field] = false;
77             if (isset($noteUpdate->$field)) {
78                 if ($note->$field != $noteUpdate->$field) {
79                     $note->$field = $noteUpdate->$field;
80                     $changed[$field] = true;
81                 }
82             }
83         }
84
85         if (!isset($noteUpdate->{'last-change-date'})
86             && ($changed['title'] || $changed['note-content'])
87         ) {
88             //no idea how to get the microseconds in there
89             $note->{'last-change-date'} = date('c');
90         }
91
92         if (!isset($noteUpdate->{'last-metadata-change-date'})) {
93             //no idea how to get the microseconds in there
94             $note->{'last-metadata-change-date'} = date('c');
95         }
96
97         if (isset($noteUpdate->{'node-content'})
98             && $note->{'note-content-version'} == 0
99         ) {
100             $note->{'note-content-version'} = 0.3;
101         }
102
103         $note->{'last-sync-revision'} = $syncRevision;
104     }
105
106     /**
107      * Loads synchronization data for the given user.
108      * Creates fresh sync data if there are none for the user.
109      *
110      * @param string $username User name
111      *
112      * @return SyncData Synchronization statistics (revision, sync guid)
113      */
114     public function loadSyncData($username)
115     {
116         $row = \OC_DB::executeAudited(
117             'SELECT * FROM `*PREFIX*grauphel_syncdata`'
118             . ' WHERE `syncdata_user` = ?',
119             array($username)
120         )->fetchRow();
121
122         if ($row === false) {
123             $syncdata = $this->getNewSyncData($username);
124             $this->saveSyncData($username, $syncdata);
125         } else {
126             $syncdata = new SyncData();
127             $syncdata->latestSyncRevision = (int) $row['syncdata_latest_sync_revision'];
128             $syncdata->currentSyncGuid    = $row['syncdata_current_sync_guid'];
129         }
130
131         return $syncdata;
132     }
133
134     /**
135      * Save synchronization data for the given user.
136      *
137      * @param string   $username User name
138      * @param SyncData $syncdata Synchronization data object
139      *
140      * @return void
141      */
142     public function saveSyncData($username, SyncData $syncdata)
143     {
144         $row = \OC_DB::executeAudited(
145             'SELECT * FROM `*PREFIX*grauphel_syncdata`'
146             . ' WHERE `syncdata_user` = ?',
147             array($username)
148         )->fetchRow();
149
150         if ($row === false) {
151             //INSERT
152             $sql = 'INSERT INTO `*PREFIX*grauphel_syncdata`'
153                 . '(`syncdata_user`, `syncdata_latest_sync_revision`, `syncdata_current_sync_guid`)'
154                 . ' VALUES(?, ?, ?)';
155             $params = array(
156                 $username,
157                 $syncdata->latestSyncRevision,
158                 $syncdata->currentSyncGuid
159             );
160         } else {
161             //UPDATE
162             $data = array(
163                 'syncdata_latest_sync_revision' => $syncdata->latestSyncRevision,
164                 'syncdata_current_sync_guid'    => $syncdata->currentSyncGuid,
165             );
166             $sql = 'UPDATE `*PREFIX*grauphel_syncdata` SET'
167                 . ' `' . implode('` = ?, `', array_keys($data)) . '` = ?'
168                 . ' WHERE `syncdata_user` = ?';
169             $params = array_values($data);
170             $params[] = $username;
171         }
172         \OC_DB::executeAudited($sql, $params);
173     }
174
175     /**
176      * Load a note from the storage.
177      *
178      * @param string  $username  User name
179      * @param string  $guid      Note identifier
180      * @param boolean $createNew Create a new note if it does not exist
181      *
182      * @return object Note object, NULL if !$createNew and note does not exist
183      */
184     public function load($username, $guid, $createNew = true)
185     {
186         $row = \OC_DB::executeAudited(
187             'SELECT * FROM `*PREFIX*grauphel_notes`'
188             . ' WHERE `note_user` = ? AND `note_guid` = ?',
189             array($username, $guid)
190         )->fetchRow();
191
192         if ($row === false) {
193             if (!$createNew) {
194                 return null;
195             }
196             return (object) array(
197                 'guid' => $guid,
198
199                 'create-date'               => null,
200                 'last-change-date'          => null,
201                 'last-metadata-change-date' => null,
202
203                 'title'                => null,
204                 'note-content'         => null,
205                 'note-content-version' => 0.3,
206
207                 'open-on-startup' => false,
208                 'pinned'          => false,
209                 'tags'            => array(),
210             );
211         }
212         
213         return $this->noteFromRow($row);
214     }
215
216     /**
217      * Save a note into storage.
218      *
219      * @param string $username User name
220      * @param object $note     Note to save
221      *
222      * @return void
223      */
224     public function save($username, $note)
225     {
226         $row = \OC_DB::executeAudited(
227             'SELECT * FROM `*PREFIX*grauphel_notes`'
228             . ' WHERE `note_user` = ? AND `note_guid` = ?',
229             array($username, $note->guid)
230         )->fetchRow();
231
232         $data = $this->rowFromNote($note);
233         if ($row === false) {
234             //INSERT
235             $data['note_user'] = $username;
236             $sql = 'INSERT INTO `*PREFIX*grauphel_notes`'
237                 . ' (`' . implode('`, `', array_keys($data)) . '`)'
238                 . ' VALUES(' . implode(', ', array_fill(0, count($data), '?')) . ')';
239             $params = array_values($data);
240         } else {
241             //UPDATE
242             $sql = 'UPDATE `*PREFIX*grauphel_notes` SET '
243                 . '`' . implode('` = ?, `', array_keys($data)) . '` = ?'
244                 . ' WHERE `note_user` = ? AND `note_guid` = ?';
245             $params = array_values($data);
246             $params[] = $username;
247             $params[] = $note->guid;
248         }
249         \OC_DB::executeAudited($sql, $params);
250     }
251
252     /**
253      * Delete a note from storage.
254      *
255      * @param string $username User name
256      * @param object $guid     ID of the note
257      *
258      * @return void
259      */
260     public function delete($username, $guid)
261     {
262         \OC_DB::executeAudited(
263             'DELETE FROM `*PREFIX*grauphel_notes`'
264             . ' WHERE `note_user` = ? AND `note_guid` = ?',
265             array($username, $guid)
266         );
267     }
268
269     /**
270      * Load notes for the given user in short form.
271      * Optionally only those changed after $since revision
272      *
273      * @param string  $username User name
274      * @param integer $since    Revision number after which the notes changed
275      *
276      * @return array Array of short note objects
277      */
278     public function loadNotesOverview($username, $since = null)
279     {
280         $result = \OC_DB::executeAudited(
281             'SELECT `note_guid`, `note_title`, `note_last_sync_revision`'
282             . ' FROM `*PREFIX*grauphel_notes`'
283             . ' WHERE note_user = ?',
284             array($username)
285         );
286
287         $notes = array();
288         while ($row = $result->fetchRow()) {
289             if ($since !== null && $row['note_last_sync_revision'] <= $since) {
290                 continue;
291             }
292             $notes[] = array(
293                 'guid' => $row['note_guid'],
294                 'ref'  => array(
295                     'api-ref' => $this->urlGen->getAbsoluteURL(
296                         $this->urlGen->linkToRoute(
297                             'grauphel.api.note',
298                             array(
299                                 'username' => $username,
300                                 'guid' => $row['note_guid']
301                             )
302                         )
303                     ),
304                     'href' => null,//FIXME
305                 ),
306                 'title' => $row['note_title'],
307             );
308         }
309
310         return $notes;
311     }
312
313     /**
314      * Load notes for the given user in full form.
315      * Optionally only those changed after $since revision
316      *
317      * @param string  $username User name
318      * @param integer $since    Revision number after which the notes changed
319      *
320      * @return array Array of full note objects
321      */
322     public function loadNotesFull($username, $since = null)
323     {
324         $result = \OC_DB::executeAudited(
325             'SELECT * FROM `*PREFIX*grauphel_notes`'
326             . ' WHERE note_user = ?',
327             array($username)
328         );
329
330         $notes = array();
331         while ($row = $result->fetchRow()) {
332             if ($since !== null && $row['note_last_sync_revision'] <= $since) {
333                 continue;
334             }
335             $notes[] = $this->noteFromRow($row);
336         }
337
338         return $notes;
339     }
340
341     protected function noteFromRow($row)
342     {
343         return (object) array(
344             'guid'  => $row['note_guid'],
345
346             'create-date'               => $row['note_create_date'],
347             'last-change-date'          => $row['note_last_change_date'],
348             'last-metadata-change-date' => $row['note_last_metadata_change_date'],
349
350             'title'                => $row['note_title'],
351             'note-content'         => $row['note_content'],
352             'note-content-version' => $row['note_content_version'],
353
354             'open-on-startup' => (bool) $row['note_open_on_startup'],
355             'pinned'          => (bool) $row['note_pinned'],
356             'tags'            => json_decode($row['note_tags']),
357
358             'last-sync-revision' => (int) $row['note_last_sync_revision'],
359         );
360     }
361
362     protected function rowFromNote($note)
363     {
364         return array(
365             'note_guid'  => $note->guid,
366             'note_title' => $note->title,
367
368             'note_content'         => $note->{'note-content'},
369             'note_content_version' => $note->{'note-content-version'},
370
371             'note_create_date'               => $note->{'create-date'},
372             'note_last_change_date'          => $note->{'last-change-date'},
373             'note_last_metadata_change_date' => $note->{'last-metadata-change-date'},
374             
375             'note_open_on_startup' => $note->{'open-on-startup'},
376             'note_pinned'          => $note->pinned,
377             'note_tags'            => json_encode($note->tags),
378
379             'note_last_sync_revision' => $note->{'last-sync-revision'},
380         );
381     }
382 }
383 ?>