OSDN Git Service

066347d11f410f8cf5f05b3388e93552901f19df
[eos/zephyr.git] / server / class / DB.js
1 /**
2  * DBを操作するクラス
3  *
4  * @returns {object}
5  */
6 function DB() {
7     'use strict';
8
9     var fs = require('fs');
10     var Sequelize = require('sequelize');
11     var co = require('co');
12     var uuid = require('node-uuid');
13
14     var sequelize;
15     var test = 'hello';
16
17     var dbOption = {
18         dialect: 'sqlite'
19     };
20
21     /**
22      * sync
23      *
24      * @returns {promise}<DBオブジェクトの関数群のオブジェクトをresolveする>
25      */
26     function sync() {
27         return new Promise(function(resolve) {
28             Files.sync()
29             .then(function() {
30                 var root = {
31                     fileId: '1f83f620-c1ed-11e5-9657-7942989daa00', // rootのuuidは固定値
32                     name: '/',
33                     parentId: '',
34                     fileType: 0
35                 };
36                 return Files.create(root);
37             })
38             .then(function() {
39                 var c = {
40                     sayHello: function() {
41                         return test;
42                     },
43                     getDirectoryParentId: getDirectoryParentId,
44                     getDirectoryId: getDirectoryId,
45                     getDirectory: getDirectory,
46                     existFile: existFile,
47                     notExistFile: notExistFile,
48                     existDirectory: existDirectory,
49                     notExistDirectory: notExistDirectory,
50                     createFile: createFile,
51                     removeFile: removeFile,
52                     createDirectory: createDirectory,
53                     test1: test1,
54                     test2: test2
55                     /*
56                        removeDirectory: removeDirectory,
57                        getFilename: getFilename,
58                        moveFile: moveFile,
59                        moveDirectory: moveDirectory
60                        */
61                 };
62                 resolve(c);
63             });
64         });
65     }
66
67     /**
68      * getDirectoryParentId
69      * ディレクトリのparentIdを取得する 
70      * @param name
71      * @returns {promise} ディレクトリが存在すればresolve(uuid), しなければreject
72      */
73     function getDirectoryParentId(name) {
74         return new Promise(function(resolve, reject) {
75             var q = {
76                 where: {
77                     name: name,
78                     fileType: 0
79                 }
80             };
81             Files.findAll(q)
82             .then(function(r) {
83                 if(r.length === 0) {
84                     reject(new Error('"' + name + '" directory doesn\'t exist.'));
85                 } else {
86                     var map = r.map(function(c) { return c.dataValues.parentId });
87                     resolve(map);
88                 }
89             });
90         });
91     }
92
93
94     /**
95      * getDirectoryId
96      * ディレクトリのfileIdを取得する 
97      * @param name
98      * @returns {promise} ディレクトリが存在すればresolve(uuid), しなければreject
99      */
100
101     function getDirectoryId(name) {
102         return new Promise(function(resolve, reject) {
103             var q = {
104                 where: {
105                     name: name,
106                     fileType: 0
107                 }
108             };
109             Files.findAll(q)
110             .then(function(r) {
111                 if(r.length === 0) {
112                     reject(new Error('"' + name + '" directory doesn\'t exist.'));
113                 } else {
114                     var map = r.map(function(c) { return c.dataValues.fileId });
115                     resolve(map);
116                 }
117             });
118         });
119     }
120
121     /**
122      * getDirectory
123      * ディレクトリのfileIdを取得する 
124      * @param name
125      * @returns {promise} ディレクトリが存在すればresolve(name), しなければreject
126      */
127
128     function getDirectory(name) {
129         return new Promise(function(resolve, reject) {
130             var q = {
131                 where: {
132                     name: name,
133                     fileType: 0
134                 }
135             };
136             Files.findAll(q)
137             .then(function(r) {
138                 if(r.length === 0) {
139                     reject(new Error('"' + name + '" directory doesn\'t exist.'));
140                 } else {
141                     var map = r.map(function(c) { return c.dataValues });
142                     resolve(map);
143                 }
144             });
145         });
146     }
147
148     /**
149      * existFile
150      * 同一ディレクトリに同名のファイルが存在することを確かめる
151      * @param {string} fileName
152      * @param {string} parentDirectory parentDirectoryの絶対パス
153      * @returns {promise} ファイルが存在すればresolve、存在しなければreject
154      */
155     function existFile(fileName, parentDirectory) {
156         return new Promise(function(resolve, reject) {
157             existDirectory(parentDirectory)
158             .catch(function(error) {
159                 reject(error);
160             })
161             .then(function(fileId) {
162                 var q = {
163                 where: {
164                     name: fileName,
165                     parentId: fileId,
166                     fileType: 1 
167                     }
168                 };
169                 return Files.findOne(q)
170             })
171             .then(function(r) {
172                 if(r === null) {
173                     reject(new Error("\"" + fileName + "\" does not exist in " + '"' + parentDirectory + "\" directory."));
174                 } else {
175                     console.log(r.fileId);
176                     resolve(r.fileId);
177                 }
178             });
179         });
180     }
181
182
183     /**
184      * notExistFile
185      * 同一ディレクトリに同名のファイルが存在していないことを確かめる
186      * @param {string}fileName
187      * @param {string}parentDirectory
188      * @returns {promise} ファイルが存在しなければresolve、存在すればreject
189      */
190     function notExistFile(fileName, parentDirectory) {
191         return new Promise(function(resolve, reject) {
192             existDirectory(parentDirectory)
193             .catch(function(error) {
194                 reject(error);
195             })
196             .then(function(fileId) {
197                 var q = {
198                 where: {
199                     name: fileName,
200                     parentId: fileId,
201                     fileType: 1 
202                     }
203                 };
204                 return Files.findOne(q)
205             })
206             .then(function(r) {
207                 if(r === null) {
208                     resolve();
209                 } else {
210                     reject(new Error("\"" + fileName + "\" has already existed in " + '"' + parentDirectory + "\" directory."));
211                 }
212             });
213         });
214     }
215
216     /**
217      * existDirectory
218      * ディレクトリが存在することを確認する
219      * @param {string} directory
220      * @returns {promise} ディレクトリが存在すればresolve{fileId)、存在しなければreject
221      */
222     function existDirectory(directory) {
223         return new Promise(function(resolve, reject) {
224             var arrayDirectory; 
225             if(directory === '/') {
226                 resolve('1f83f620-c1ed-11e5-9657-7942989daa00');
227             } else {
228                 arrayDirectory = directory.split('/');
229                 arrayDirectory.shift(); // root
230                 arrayDirectory.unshift('/');
231             }
232
233             var directoriesPromise = arrayDirectory.map(function(name) {
234                 return getDirectory(name);
235             });
236             Promise.all(directoriesPromise)
237             .then(function(r) {
238                 var parentId = r[0][0].fileId;
239                 var index;
240                 for(var i=1;i<r.length;i++) {
241                     index = r[i].map(function(c) { return c.parentId }).indexOf(parentId);
242                     if(index > -1) {
243                         parentId = r[i][index].fileId;
244                     } else {
245                         reject(new Error('"' + directory + '" directory doesn\'t exist.'));
246                     }
247                 }
248                 resolve(parentId);
249             })
250             .catch(function(error) {
251                 reject(new Error('"' + directory + '" directory doesn\'t exist.'));
252             });
253         });
254     }
255
256     /**
257      * notExistDirectory
258      * ディレクトリが存在しないことを確認する
259      * @param {string} directory
260      * @returns {promise} ディレクトリが存在しなければresolve、存在すればreject
261      */
262     function notExistDirectory(directory) {
263         return new Promise(function(resolve, reject) {
264             var arrayDirectory; 
265             if(directory === '/') {
266                 reject(new Error('"' + directory + '" directory exists.'));
267             } else {
268                 arrayDirectory = directory.split('/');
269                 arrayDirectory.shift(); // root
270                 arrayDirectory.unshift('/');
271             }
272
273             var directoriesPromise = arrayDirectory.map(function(name) {
274                 return getDirectory(name);
275             });
276             Promise.all(directoriesPromise)
277             .then(function(r) {
278                 var parentId = r[0][0].fileId;
279                 var index;
280                 for(var i=1;i<r.length;i++) {
281                     index = r[i].map(function(c) { return c.parentId }).indexOf(parentId);
282                     if(index > -1) {
283                         parentId = r[i][index].fileId;
284                     } else {
285                         resolve();
286                     }
287                 }
288                 reject(new Error('"' + directory + '" directory exists.'));
289             })
290             .catch(function(error) {
291                 resolve();
292             });
293         });
294     }
295
296     /**
297      * createFile
298      *
299      * @param fileName 
300      * @param parentDirectory
301      * @returns {promise}<sequelize.createの結果を格納したobject | Error>
302      */
303     function createFile(fileName,parentDirectory) {
304         return new Promise(function(resolve, reject) {
305             Promise.all([existDirectory(parentDirectory), notExistFile(fileName, parentDirectory) ])
306             .catch(function(error) {
307                 reject(error);
308             })
309             .then(function(r) {
310                 var parentId = r[0]
311                 var q = {
312                     fileId: uuid.v1(),
313                     name: fileName,
314                     parentId: parentId,
315                     fileType: 1 
316                 }
317                 return Files.create(q)
318             })
319             .then(function(r) {
320                 resolve(r.dataValues.fileId);
321             });
322         });
323     }
324
325
326     /**
327      * removeFile
328      * ファイルを削除する
329      * @param {string} fileName
330      * @param {string} parentDirectory
331      * @returns {promise} ファイル削除に成功すればresolve、失敗すればreject
332      */
333     function removeFile(fileName, parentDirectory) {
334         return new Promise(function(resolve, reject) {
335             existFile(fileName, parentDirectory)
336             .catch(function(error) {
337                 reject(error);
338             })
339             .then(function(fileId) {
340                 var q = {
341                     where: {
342                         fileId: fileId
343                     }
344                 };
345                 return Files.destroy(q);
346             })
347             .then(function() {
348                 resolve();
349             });
350         });
351     }
352
353     /**
354      * createDirectory
355      *
356      * @param fileName 
357      * @param parentDirectory
358      * @returns {promise}<sequelize.createの結果を格納したobject | Error>
359      */
360     function createDirectory(fileName,parentDirectory) {
361         return new Promise(function(resolve, reject) {
362             Promise.all([notExistFile(fileName, parentDirectory), existDirectory(parentDirectory)])
363             .catch(function(error) {
364                 reject(error);
365             })
366             .then(function() {
367                 var q = {
368                     fileId: uuid.v1(),
369                     name: fileName,
370                     parentDirectory: parentDirectory,
371                     fileType: 1 
372                 }
373                 return Files.create(q)
374             })
375             .then(function(r) {
376                 resolve(r.dataValues.fileId);
377             });
378         });
379     }
380
381     /**
382      * test1
383      * test用にデータベースのレコードを追加する関数
384      * @returns {promise}
385      */
386     function test1() {
387         var q = {
388             fileId: uuid.v1(),
389             name: 'hoge.txt',
390             parentId: '1f83f620-c1ed-11e5-9657-7942989daa00', // rootのuuid
391             fileType: 1 
392         };
393         return Files.create(q);
394     }
395
396     /**
397      * test2
398      * test用にデータベースのレコードを追加する関数
399      * @returns {promise}
400      */
401
402     function test2() {
403         var q1 = {
404             fileId: uuid.v1(),
405             name: 'one',
406             parentId: '1f83f620-c1ed-11e5-9657-7942989daa00', // rootのuuid
407             fileType: 0 
408         };
409         return Files.create(q1)
410         .then(function() {
411             var q2 = {
412                 fileId: uuid.v1(),
413                 name: 'two',
414                 parentId: q1.fileId,
415                 fileType: 0 
416
417             };
418             return Files.create(q2);
419         })
420         .then(function(r) {
421             var q3 = {
422                 fileId: uuid.v1(),
423                 name: 'two',
424                 parentId: '1f83f620-c1ed-11e5-9657-7942989daa00',
425                 fileType: 0 
426             };
427             return Files.create(q3);
428         })
429         .then(function() {
430             var q4 = {
431                 fileId: uuid.v1(),
432                 name: 'hogehoge.txt',
433                 parentId: q1.fileId,
434                 fileType: 1
435             };
436             return Files.create(q4);
437         });
438     }
439
440
441     /**
442      * 
443      * @constructor
444      * @returns {promise}
445      */
446     if(process.env['NODE_ENV'] === 'production') {
447         var dbPath = __dirname + '/../../user-specific-files/db/db.workspace';
448         dbOption.storage = dbPath;
449
450         // if doesn't exist workspace.db, create.
451         try {
452             fs.accessSync(dbPath, fs.R_OK | fs.W_OK);
453         } catch(e) {
454             fs.writeFileSync(dbPath, '');
455         }
456     }
457
458     sequelize = new Sequelize('','','', dbOption);
459
460     var Files = sequelize.define('file', {
461         fileId: {
462             type: Sequelize.UUID,
463             field: 'file_id',
464             primaryKey: true
465         },
466         name: {
467             type: Sequelize.STRING,
468             field: 'name',
469             allowNull: false
470         },
471         parentId: {
472             type: Sequelize.UUID,
473             field: 'parent_id',
474             allowNull: false
475         },
476         fileType: {
477             type: Sequelize.ENUM(0,1),
478             field: 'file_type',
479             allowNull: false
480         }
481     });
482
483     return sync();
484 }
485
486 module.exports = DB;