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 existFileId: existFileId,
29 notExistFile: notExistFile,
30 existDirectory: existDirectory,
31 notExistDirectory: notExistDirectory,
32 createFile: createFile,
33 removeFile: removeFile,
34 createDirectory: createDirectory,
39 removeDirectory: removeDirectory,
40 getFilename: getFilename,
42 moveDirectory: moveDirectory
53 * productionモード時は、db.workspaceを永続化させる
54 * DEBUGモードの時は、db.debugを実行毎に作成する。
55 * DEBUGモードの時は、sync()の中で、/レコードがFilesテーブルに追加される。
56 * モードの切り替えは環境変数NODE_ENVで行っている。
57 * zephyr serveコマンドが実行されるとNODE_ENV = 'production'
58 * zephyr debugコマンドが実行されるとNODE_ENV = 'debug'
60 * それぞれの設定は$ZEOHYR_HOME/cli/zephyr-serve, $ZEPHYR_HOME/zephyre_debugを参照
69 if(process.env['NODE_ENV'] === 'production') {
70 dbPath = __dirname + '/../../user-specific-files/db/db.workspace';
71 process.env['WorkspacePATH']= __dirname + '/../../user-specific-files/workspace';
73 // if doesn't exist workspace.db, create.
75 fs.accessSync(dbPath, fs.R_OK | fs.W_OK);
77 fs.writeFileSync(dbPath, '');
79 dbOption.storage = dbPath;
81 } else if(process.env['NODE_ENV'] === 'debug') {
82 dbPath = __dirname + '/../../user-specific-files/db/db.debug';
83 process.env['WorkspacePATH']= __dirname + '/../../user-specific-files/workspace.debug';
86 fs.accessSync(dbPath, fs.R_OK | fs.W_OK);
87 fs.unlinkSync(dbPath);
91 fs.writeFileSync(dbPath, '');
92 dbOption.storage = dbPath;
94 var workspacePath = process.env['WorkspacePATH'];
96 sequelize = new Sequelize('','','', dbOption);
98 Files = sequelize.define('file', {
100 type: Sequelize.UUID,
105 type: Sequelize.STRING,
110 type: Sequelize.UUID,
115 type: Sequelize.ENUM(0,1),
121 var force = process.env.NODE_ENV !== 'production';
122 return Files.sync({force: force})
135 * @returns {promise}<DBオブジェクトの関数群のオブジェクトをresolveする>
137 function insertRoot() {
138 return new Promise(function(resolve, reject) {
148 fileId: '1f83f620-c1ed-11e5-9657-7942989daa00', // rootのuuidは固定値
153 return Files.create(root);
163 * getDirectoryParentId
164 * ディレクトリのparentIdを取得する
166 * @returns {promise} ディレクトリが存在すればresolve(uuid), しなければreject
168 function getDirectoryParentId(name) {
169 return new Promise(function(resolve, reject) {
179 reject(new Error('"' + name + '" directory doesn\'t exist.'));
181 var map = r.map(function(c) { return c.dataValues.parentId });
193 * @returns {promise} ディレクトリが存在すればresolve(uuid), しなければreject
196 function getDirectoryId(name) {
197 return new Promise(function(resolve, reject) {
207 reject(new Error('"' + name + '" directory doesn\'t exist.'));
209 var map = r.map(function(c) { return c.dataValues.fileId });
220 * @returns {promise} ディレクトリが存在すればresolve(name), しなければreject
223 function getDirectory(name) {
224 return new Promise(function(resolve, reject) {
234 reject(new Error('"' + name + '" directory doesn\'t exist.'));
236 var map = r.map(function(c) { return c.dataValues });
245 * ディレクトリのfileId一覧を取得する
246 * @param {string} fileId ディレクトリのfileId
247 * @returns {promise} resolve([Array]<string>fileId) 引数で与えられたディレクトリを直接の親に持つファイルのレコードの配列を返す。
248 * 与えられたfileIdがディレクトリでなければresolve
250 function getFiles(fileId) {
251 return new Promise(function(resolve, reject) {
253 reject(new Error('"'+fileId+'" is invalid.'));
263 reject(new Error('"'+fileId+'" is invalid.'));
265 var files = r.map(function(data) { return data; });
274 * @returns {promise} resolve([Array]<Object>)
276 function getDirectories() {
277 return new Promise(function(resolve, reject) {
285 var dirs = r.map(function(data) {
286 return data.dataValues;
295 * 同一ディレクトリに同名のファイルが存在することを確かめる
296 * @param {string} fileName
297 * @param {string} parentDirectory parentDirectoryの絶対パス
298 * @returns {promise} ファイルが存在すればresolve、存在しなければreject
300 function existFile(fileName, parentDirectory) {
301 return new Promise(function(resolve, reject) {
302 existDirectory(parentDirectory)
303 .catch(function(error) {
306 .then(function(fileId) {
313 return Files.findOne(q)
317 reject(new Error("\"" + fileName + "\" does not exist in " + '"' + parentDirectory + "\" directory."));
327 * 同一ディレクトリに同名のファイルが存在することを確かめる
328 * @param {string} fileId
329 * @param {string} parentDirectory parentDirectoryの絶対パス
330 * @returns {promise} ファイルが存在すればresolve、存在しなければreject
332 function existFileId(whichfileID, parentDirectory) {
333 console.log('findFileId start');
335 return new Promise(function(resolve, reject) {
336 existDirectory(parentDirectory)
337 .catch(function(error) {
340 .then(function(fileId) {
341 console.log('findFileId: '+whichfileID);
342 var q = Files.findOne({
348 console.log('findFileId: get q'+q.tostring);
357 reject(new Error("\"" + fileName + "\" does not exist in " + '"' + parentDirectory + "\" directory."));
368 * 同一ディレクトリに同名のファイルが存在していないことを確かめる
369 * @param {string}fileName
370 * @param {string}parentDirectory
371 * @returns {promise} ファイルが存在しなければresolve、存在すればreject
373 function notExistFile(fileName, parentDirectory) {
374 return new Promise(function(resolve, reject) {
375 existDirectory(parentDirectory)
376 .catch(function(error) {
379 .then(function(fileId) {
386 return Files.findOne(q)
392 reject(new Error("\"" + fileName + "\" has already existed in " + '"' + parentDirectory + "\" directory."));
401 * @param {string} directory
402 * @returns {promise} ディレクトリが存在すればresolve{fileId)、存在しなければreject
404 function existDirectory(directory) {
405 return new Promise(function(resolve, reject) {
407 reject(new Error('parameter "directory" is undefined'));
411 var root = directory.substr(0,1);
414 reject(new Error('directory name should start "/" so that it is absolute path including root.'));
417 if(directory === '/') {
418 resolve('1f83f620-c1ed-11e5-9657-7942989daa00'); // rootのuuid
420 arrayDirectory = directory.split('/');
421 arrayDirectory.shift(); // root
422 arrayDirectory.unshift('/');
425 var directoriesPromise = arrayDirectory.map(function(name) {
426 return getDirectory(name);
429 Promise.all(directoriesPromise)
431 var parentId = r[0][0].fileId;
433 for(var i=1;i<r.length;i++) {
434 index = r[i].map(function(c) { return c.parentId }).indexOf(parentId);
436 parentId = r[i][index].fileId;
438 reject(new Error('"' + directory + '" directory doesn\'t exist.'));
443 .catch(function(error) {
444 reject(new Error('"' + directory + '" directory doesn\'t exist.'));
451 * ディレクトリが存在しないことを確認する
452 * @param {string} directory
453 * @returns {promise} ディレクトリが存在しなければresolve、存在すればreject
455 function notExistDirectory(directory) {
456 return new Promise(function(resolve, reject) {
462 var root = directory.substr(0,1);
468 if(directory === '/') {
469 reject(new Error('"' + directory + '" directory exists.'));
471 arrayDirectory = directory.split('/');
472 arrayDirectory.shift(); // root
473 arrayDirectory.unshift('/');
476 var directoriesPromise = arrayDirectory.map(function(name) {
477 return getDirectory(name);
479 Promise.all(directoriesPromise)
481 var parentId = r[0][0].fileId;
483 for(var i=1;i<r.length;i++) {
484 index = r[i].map(function(c) { return c.parentId }).indexOf(parentId);
486 parentId = r[i][index].fileId;
491 reject(new Error('"' + directory + '" directory exists.'));
493 .catch(function(error) {
503 * @param parentDirectory
504 * @returns {promise}<sequelize.createの結果を格納したobject | Error>
506 function createFile(fileName,parentDirectory) {
507 return new Promise(function(resolve, reject) {
509 reject(new Error('filename is required.'));
511 Promise.all([existDirectory(parentDirectory), notExistFile(fileName, parentDirectory) ])
512 .catch(function(error) {
524 console.log('createFile:'+process.env['WorkspacePATH']+parentDirectory+fileName);
525 console.log('createFile:'+process.env['WorkspacePATH']+parentDirectory+q.fileId);
526 //console.log('createFile:'+workspacePath+parentDirectory+fileName);
527 //console.log('createFile:'+workspacePath+parentDirectory+r.dataValues.fileId);
529 fs.rename(process.env['WorkspacePATH']+parentDirectory+fileName, process.env['WorkspacePATH']+parentDirectory+q.fileId, function (err) {
531 console.log('renamed complete');
534 return Files.create(q)
537 resolve(r.dataValues.fileId);
546 * @param {string} fileName
547 * @param {string} parentDirectory
548 * @returns {promise} ファイル削除に成功すればresolve、失敗すればreject
550 function removeFile(fileName, parentDirectory) {
551 return new Promise(function(resolve, reject) {
552 existFile(fileName, parentDirectory)
553 .catch(function(error) {
556 .then(function(fileId) {
562 return Files.destroy(q);
574 * @returns {promise} ディレクトリの作成に成功すればresolve、失敗すればreject
576 function createDirectory(directory) {
577 return new Promise(function(resolve, reject) {
579 reject(new Error('directory name should start "/" so that it is absolute path including root.'));
582 var leaf = directory.split('/').pop();
583 var parentDirectory = directory.replace('/'+leaf, '');
584 if(!parentDirectory) {
585 parentDirectory = '/';
587 Promise.all([existDirectory(parentDirectory), notExistDirectory(directory), notExistFile(leaf, parentDirectory)])
588 .catch(function(error) {
599 return Files.create(q)
602 resolve(r.dataValues.fileId);
612 * @returns {promise} ディレクトリの削除に成功すればresolve、失敗すればreject
614 function removeDirectory(directory) {
615 return new Promise(function(resolve, reject) {
616 var leaf = directory.split('/').pop();
617 var parentDirectory = directory.replace('/'+leaf, '');
618 if(!parentDirectory) {
619 parentDirectory = '/';
621 Promise.all([existDirectory(parentDirectory), notExistDirectory(directory), notExistFile(leaf, parentDirectory)])
622 .catch(function(error) {
633 return Files.create(q)
636 resolve(r.dataValues.fileId);
643 * test用にデータベースのレコードを追加する関数
651 parentId: '1f83f620-c1ed-11e5-9657-7942989daa00', // rootのuuid
654 return Files.create(q);
659 * test用にデータベースのレコードを追加する関数
665 fileId: '1f83f620-c1ed-11e5-9657-7942989daa04',
667 parentId: '1f83f620-c1ed-11e5-9657-7942989daa00', // rootのuuid
668 fileType: 0 //directory
670 return Files.create(q1)
673 fileId: '1f83f620-c1ed-11e5-9657-7942989daa01',
679 return Files.create(q2);
683 fileId: '1f83f620-c1ed-11e5-9657-7942989daa02',
685 parentId: '1f83f620-c1ed-11e5-9657-7942989daa00', //rootのuuid
688 return Files.create(q3);
692 fileId:'1f83f620-c1ed-11e5-9657-7942989daa03',
693 name: 'hogehoge.txt',
697 return Files.create(q4);
702 function testRest() {
704 fileId: '54998540-f62c-11e6-abc9-45e2912c9ebf',
705 name: 'debugRest.mrc',
706 parentId: '1f83f620-c1ed-11e5-9657-7942989daa00', //rootのuuid
709 return Files.create(q);
712 module.exports = { instance: instance };