8 var fs = require('fs');
9 var Sequelize = require('sequelize');
10 var co = require('co');
11 var uuid = require('node-uuid');
15 var Files; // Model object of sequelize
19 sayHello: function() {
22 getDirectoryParentId: getDirectoryParentId,
23 getDirectoryId: getDirectoryId,
24 getDirectory: getDirectory,
26 getDirectories: getDirectories,
28 notExistFile: notExistFile,
29 existDirectory: existDirectory,
30 notExistDirectory: notExistDirectory,
31 createFile: createFile,
32 removeFile: removeFile,
33 createDirectory: createDirectory,
38 removeDirectory: removeDirectory,
39 getFilename: getFilename,
41 moveDirectory: moveDirectory
52 * productionモード時は、db.workspaceを永続化させる
53 * DEBUGモードの時は、db.debugを実行毎に作成する。
54 * DEBUGモードの時は、sync()の中で、/レコードがFilesテーブルに追加される。
55 * モードの切り替えは環境変数NODE_ENVで行っている。
56 * zephyr serveコマンドが実行されるとNODE_ENV = 'production'
57 * zephyr debugコマンドが実行されるとNODE_ENV = 'debug'
59 * それぞれの設定は$ZEOHYR_HOME/cli/zephyr-serve, $ZEPHYR_HOME/zephyre_debugを参照
68 if(process.env['NODE_ENV'] === 'production') {
69 dbPath = __dirname + '/../../user-specific-files/db/db.workspace';
70 // if doesn't exist workspace.db, create.
72 fs.accessSync(dbPath, fs.R_OK | fs.W_OK);
74 fs.writeFileSync(dbPath, '');
76 dbOption.storage = dbPath;
78 } else if(process.env['NODE_ENV'] === 'debug') {
79 dbPath = __dirname + '/../../user-specific-files/db/db.debug';
81 fs.accessSync(dbPath, fs.R_OK | fs.W_OK);
82 fs.unlinkSync(dbPath);
86 fs.writeFileSync(dbPath, '');
87 dbOption.storage = dbPath;
90 sequelize = new Sequelize('','','', dbOption);
92 Files = sequelize.define('file', {
99 type: Sequelize.STRING,
104 type: Sequelize.UUID,
109 type: Sequelize.ENUM(0,1),
115 var force = process.env.NODE_ENV !== 'production';
116 return Files.sync({force: force})
126 * @returns {promise}<DBオブジェクトの関数群のオブジェクトをresolveする>
128 function insertRoot() {
129 return new Promise(function(resolve, reject) {
139 fileId: '1f83f620-c1ed-11e5-9657-7942989daa00', // rootのuuidは固定値
144 return Files.create(root);
154 * getDirectoryParentId
155 * ディレクトリのparentIdを取得する
157 * @returns {promise} ディレクトリが存在すればresolve(uuid), しなければreject
159 function getDirectoryParentId(name) {
160 return new Promise(function(resolve, reject) {
170 reject(new Error('"' + name + '" directory doesn\'t exist.'));
172 var map = r.map(function(c) { return c.dataValues.parentId });
184 * @returns {promise} ディレクトリが存在すればresolve(uuid), しなければreject
187 function getDirectoryId(name) {
188 return new Promise(function(resolve, reject) {
198 reject(new Error('"' + name + '" directory doesn\'t exist.'));
200 var map = r.map(function(c) { return c.dataValues.fileId });
211 * @returns {promise} ディレクトリが存在すればresolve(name), しなければreject
214 function getDirectory(name) {
215 return new Promise(function(resolve, reject) {
225 reject(new Error('"' + name + '" directory doesn\'t exist.'));
227 var map = r.map(function(c) { return c.dataValues });
236 * ディレクトリのfileId一覧を取得する
237 * @param {string} fileId ディレクトリのfileId
238 * @returns {promise} resolve([Array]<string>fileId) 引数で与えられたディレクトリを直接の親に持つファイルのレコードの配列を返す。
239 * 与えられたfileIdがディレクトリでなければresolve
241 function getFiles(fileId) {
242 return new Promise(function(resolve, reject) {
244 reject(new Error('"'+fileId+'" is invalid.'));
254 reject(new Error('"'+fileId+'" is invalid.'));
256 var files = r.map(function(data) { return data; });
265 * @returns {promise} resolve([Array]<Object>)
267 function getDirectories() {
268 return new Promise(function(resolve, reject) {
276 var dirs = r.map(function(data) {
277 return data.dataValues;
286 * 同一ディレクトリに同名のファイルが存在することを確かめる
287 * @param {string} fileName
288 * @param {string} parentDirectory parentDirectoryの絶対パス
289 * @returns {promise} ファイルが存在すればresolve、存在しなければreject
291 function existFile(fileName, parentDirectory) {
292 return new Promise(function(resolve, reject) {
293 existDirectory(parentDirectory)
294 .catch(function(error) {
297 .then(function(fileId) {
304 return Files.findOne(q)
308 reject(new Error("\"" + fileName + "\" does not exist in " + '"' + parentDirectory + "\" directory."));
319 * 同一ディレクトリに同名のファイルが存在していないことを確かめる
320 * @param {string}fileName
321 * @param {string}parentDirectory
322 * @returns {promise} ファイルが存在しなければresolve、存在すればreject
324 function notExistFile(fileName, parentDirectory) {
325 return new Promise(function(resolve, reject) {
326 existDirectory(parentDirectory)
327 .catch(function(error) {
330 .then(function(fileId) {
337 return Files.findOne(q)
343 reject(new Error("\"" + fileName + "\" has already existed in " + '"' + parentDirectory + "\" directory."));
352 * @param {string} directory
353 * @returns {promise} ディレクトリが存在すればresolve{fileId)、存在しなければreject
355 function existDirectory(directory) {
356 return new Promise(function(resolve, reject) {
358 reject(new Error('parameter "directory" is undefined'));
362 var root = directory.substr(0,1);
365 reject(new Error('directory name should start "/" so that it is absolute path including root.'));
368 if(directory === '/') {
369 resolve('1f83f620-c1ed-11e5-9657-7942989daa00'); // rootのuuid
371 arrayDirectory = directory.split('/');
372 arrayDirectory.shift(); // root
373 arrayDirectory.unshift('/');
376 var directoriesPromise = arrayDirectory.map(function(name) {
377 return getDirectory(name);
380 Promise.all(directoriesPromise)
382 var parentId = r[0][0].fileId;
384 for(var i=1;i<r.length;i++) {
385 index = r[i].map(function(c) { return c.parentId }).indexOf(parentId);
387 parentId = r[i][index].fileId;
389 reject(new Error('"' + directory + '" directory doesn\'t exist.'));
394 .catch(function(error) {
395 reject(new Error('"' + directory + '" directory doesn\'t exist.'));
402 * ディレクトリが存在しないことを確認する
403 * @param {string} directory
404 * @returns {promise} ディレクトリが存在しなければresolve、存在すればreject
406 function notExistDirectory(directory) {
407 return new Promise(function(resolve, reject) {
413 var root = directory.substr(0,1);
419 if(directory === '/') {
420 reject(new Error('"' + directory + '" directory exists.'));
422 arrayDirectory = directory.split('/');
423 arrayDirectory.shift(); // root
424 arrayDirectory.unshift('/');
427 var directoriesPromise = arrayDirectory.map(function(name) {
428 return getDirectory(name);
430 Promise.all(directoriesPromise)
432 var parentId = r[0][0].fileId;
434 for(var i=1;i<r.length;i++) {
435 index = r[i].map(function(c) { return c.parentId }).indexOf(parentId);
437 parentId = r[i][index].fileId;
442 reject(new Error('"' + directory + '" directory exists.'));
444 .catch(function(error) {
454 * @param parentDirectory
455 * @returns {promise}<sequelize.createの結果を格納したobject | Error>
457 function createFile(fileName,parentDirectory) {
458 return new Promise(function(resolve, reject) {
460 reject(new Error('filename is required.'));
462 Promise.all([existDirectory(parentDirectory), notExistFile(fileName, parentDirectory) ])
463 .catch(function(error) {
474 return Files.create(q)
477 resolve(r.dataValues.fileId);
486 * @param {string} fileName
487 * @param {string} parentDirectory
488 * @returns {promise} ファイル削除に成功すればresolve、失敗すればreject
490 function removeFile(fileName, parentDirectory) {
491 return new Promise(function(resolve, reject) {
492 existFile(fileName, parentDirectory)
493 .catch(function(error) {
496 .then(function(fileId) {
502 return Files.destroy(q);
514 * @returns {promise} ディレクトリの作成に成功すればresolve、失敗すればreject
516 function createDirectory(directory) {
517 return new Promise(function(resolve, reject) {
519 reject(new Error('directory name should start "/" so that it is absolute path including root.'));
522 var leaf = directory.split('/').pop();
523 var parentDirectory = directory.replace('/'+leaf, '');
524 if(!parentDirectory) {
525 parentDirectory = '/';
527 Promise.all([existDirectory(parentDirectory), notExistDirectory(directory), notExistFile(leaf, parentDirectory)])
528 .catch(function(error) {
539 return Files.create(q)
542 resolve(r.dataValues.fileId);
552 * @returns {promise} ディレクトリの削除に成功すればresolve、失敗すればreject
554 function removeDirectory(directory) {
555 return new Promise(function(resolve, reject) {
556 var leaf = directory.split('/').pop();
557 var parentDirectory = directory.replace('/'+leaf, '');
558 if(!parentDirectory) {
559 parentDirectory = '/';
561 Promise.all([existDirectory(parentDirectory), notExistDirectory(directory), notExistFile(leaf, parentDirectory)])
562 .catch(function(error) {
573 return Files.create(q)
576 resolve(r.dataValues.fileId);
583 * test用にデータベースのレコードを追加する関数
590 parentId: '1f83f620-c1ed-11e5-9657-7942989daa00', // rootのuuid
593 return Files.create(q);
598 * test用にデータベースのレコードを追加する関数
604 fileId: '1f83f620-c1ed-11e5-9657-7942989daa04',
606 parentId: '1f83f620-c1ed-11e5-9657-7942989daa00', // rootのuuid
607 fileType: 0 //directory
609 return Files.create(q1)
612 fileId: '1f83f620-c1ed-11e5-9657-7942989daa01',
618 return Files.create(q2);
622 fileId: '1f83f620-c1ed-11e5-9657-7942989daa02',
624 parentId: '1f83f620-c1ed-11e5-9657-7942989daa00', //rootのuuid
627 return Files.create(q3);
631 fileId:'1f83f620-c1ed-11e5-9657-7942989daa03',
632 name: 'hogehoge.txt',
636 return Files.create(q4);
640 function testRest() {
642 fileId: 'dca94750-c44f-11e5-88c4-f31cdfe97f4f',
643 name: 'debugRest.mrc',
644 parentId: '1f83f620-c1ed-11e5-9657-7942989daa00', //rootのuuid
647 return Files.create(q);
650 module.exports = { instance: instance };