From ecc3377c0ea53eab9eeab37d4993612a44bcd7d3 Mon Sep 17 00:00:00 2001 From: hawklithm Date: Thu, 2 Oct 2014 23:43:55 +0800 Subject: [PATCH] fixed the character error and can store string data into mogilefs --- lib/domain.js | 2 +- test/domain.js | 29 ++++++++++++++++++++--------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/lib/domain.js b/lib/domain.js index aa61585..6d0bd9d 100644 --- a/lib/domain.js +++ b/lib/domain.js @@ -1 +1 @@ -var url = require('url'), http = require('http'), fs = require('fs'), noop = function() {}, streamifier = require('streamifier'); /** * Constructor * * @param {Mogile} mogile Instance of the Mogile class * @param {String} name The domain name */ var Domain = function(mogile, name) { this.mogile = mogile; this.name = name; } /** * Factory method * * Returns a new instance of the Domain class * * @param {Mogile} mogile Instance of the Mogile class * @param {String} name The domain name * @return {Domain} */ Domain.factory = function(mogile, name) { return new Domain(mogile, name); } /** * Returns the paths for a given key * * @param {String} key The storage key * @param {Boolean} noverify Don't have MogileFS check that the file exists * @param {Function} callback Function that receives an array of paths for the given storage key * @return {Boolean} */ Domain.prototype.getPaths = function(key, noverify, callback) { callback = callback || noop; var args = { key: key, noverify: ((noverify) ? '1' : '0') }; this.mogile.send(this.name, 'GET_PATHS', args, function(err, response) { if (err) { return callback(err); } var paths = []; for(var i = 1; i <= response['paths']; i++) { paths.push(response['path' + i]); } callback(null, paths); }); return true; } /** * Deletes the file with the given key * * @param {String} key The storage key * @param {String} storage_class Optional. The storage class. Only required when using transactions * @param {Function} callback Function to call when the delete is complete * @return {Boolean} */ Domain.prototype.del = function(key, storage_class, callback) { if (typeof storage_class == 'function') { callback = storage_class; storage_class = null; } callback = callback || noop; var args = { "key": key, "class": storage_class }; this.mogile.send(this.name, 'DELETE', args, function(err, response) { if (err) { return callback(err); } callback(); }); } /** * Renames a file from one key to another * * @param {String} from_key The original key * @param {String} to_key The new key * @param {Function} callback Function to call when the rename is complete * @return {Boolean} */ Domain.prototype.rename = function(from_key, to_key, callback) { callback = callback || noop; var args = { "from_key": from_key, "to_key": to_key }; this.mogile.send(this.name, 'RENAME', args, function(err, response) { if (err) { return callback(err); } callback(); }); } /** * Gets the file with the given key, and writes it to a local file * * @param {String} key The storage key * @param {String} local The location to write the file to * @param {Function} callback Function to call when the local file has been written. Receives the number of bytes read. * @return {Boolean} */ Domain.prototype.getFile = function(key, local, callback) { callback = callback || noop; var bytes_written = 0; var paused = false; var response = null; this.getPaths(key, 0, function(err, paths) { if (err) { return callback(err); } var write_options = { flags: 'w+', mode: 0666 }; var stream = fs.createWriteStream(local, write_options); stream.on('open', function(fd) { var url_parts = url.parse(paths[0]); var get_options = { host: url_parts.hostname, port: url_parts.port, path: url_parts.pathname }; var get = http.get(get_options, function(res) { response = res; res.on('data', function(data) { bytes_written += data.length; var drained = stream.write(data); if (!drained) { res.pause(); paused = true; } }); res.on('end', function() { var finished = function() { if (paused) { process.nextTick(finished); } else { stream.end(); return callback(null, bytes_written); } } finished(); }); }); get.on('error', function(e) { stream.end(); return callback(e); }); }); stream.on('error', function(e) { return callback(e); }); stream.on('drain', function() { if (paused) { if (!response.complete) response.resume(); paused = false; } }); }); return true; } /** * Stores a file with the given key, in the given storage class, from the local file * * @param {String} key The storage key to save the file as * @param {String} storage_class The storage class * @param {String} local The local file to read from * @param {Function} callback Function to call when the operation is complete. Receives the number of bytes stored. * @return {Boolean} */ Domain.prototype.storeFile = function(key, storage_class, local, callback) { callback = callback || noop; var $this = this; var args = { "key": key, "class": storage_class }; $this.mogile.send($this.name, 'CREATE_OPEN', args, function(err, response) { if (err) { return callback(err); } // Typical response: { devid: '95', fid: '504917521', path: 'http://127.0.0.1:7500/dev95/0/504/917/0504917521.fid' } fs.stat(local, function(err, stat) { if (err) { return callback(err); } var path = url.parse(response.path); var options = { "host": path.hostname, "port": parseFloat(path.port), "path": path.pathname, "method": "PUT", "headers": { "Content-Length": stat.size } }; var request = http.request(options); request.on('error', function(err) { return callback(err); }); var stream = fs.createReadStream(local, { bufferSize: 512 * 1024 }); stream.pipe(request); stream.on('end', function() { request.end(); var args = { "key": key, "class": storage_class, "devid": response.devid, "fid": response.fid, "path": response.path }; $this.mogile.send($this.name, 'CREATE_CLOSE', args, function(err, response) { if (err) { return callback(err); } callback(null, stat.size); }); }); }); }); } /** * Stores a String with the given key, in the given storage class, from the input string * * @param {String} key The storage key to save the file as * @param {String} storage_class The storage class * @param {String} data the string data you want to store * @param {Function} callback Function to call when the operation is complete. Receives the number of bytes stored. * @return {Boolean} */ Domain.prototype.storeData = function(key, storage_class, data, callback) { callback = callback || noop; var $this = this; var args = { "key": key, "class": storage_class }; $this.mogile.send($this.name, 'CREATE_OPEN', args, function(err, response) { if (err) { return callback(err); } // Typical response: { devid: '95', fid: '504917521', path: 'http://127.0.0.1:7500/dev95/0/504/917/0504917521.fid' } // fs.stat(local, function(err, stat) { // if (err) { // return callback(err); // } var path = url.parse(response.path); var options = { "host": path.hostname, "port": parseFloat(path.port), "path": path.pathname, "method": "PUT", "headers": { "Content-Length": data.length } }; var request = http.request(options); request.on('error', function(err) { return callback(err); }); var stream = streamifier.createReadStream(data,{bufferSize: 512 * 1024}); // var stream = fs.createReadStream(local, { bufferSize: 512 * 1024 }); stream.pipe(request); stream.on('end', function() { request.end(); var args = { "key": key, "class": storage_class, "devid": response.devid, "fid": response.fid, "path": response.path }; $this.mogile.send($this.name, 'CREATE_CLOSE', args, function(err, response) { if (err) { return callback(err); } callback(null, data.size); }); }); // }); }); } // Export the Domain class module.exports = Domain; \ No newline at end of file +var url = require('url'), http = require('http'), fs = require('fs'), noop = function() {}, streamifier = require('streamifier'); /** * Constructor * * @param {Mogile} mogile Instance of the Mogile class * @param {String} name The domain name */ var Domain = function(mogile, name) { this.mogile = mogile; this.name = name; } /** * Factory method * * Returns a new instance of the Domain class * * @param {Mogile} mogile Instance of the Mogile class * @param {String} name The domain name * @return {Domain} */ Domain.factory = function(mogile, name) { return new Domain(mogile, name); } /** * Returns the paths for a given key * * @param {String} key The storage key * @param {Boolean} noverify Don't have MogileFS check that the file exists * @param {Function} callback Function that receives an array of paths for the given storage key * @return {Boolean} */ Domain.prototype.getPaths = function(key, noverify, callback) { callback = callback || noop; var args = { key: key, noverify: ((noverify) ? '1' : '0') }; this.mogile.send(this.name, 'GET_PATHS', args, function(err, response) { if (err) { return callback(err); } var paths = []; for(var i = 1; i <= response['paths']; i++) { paths.push(response['path' + i]); } callback(null, paths); }); return true; } /** * Deletes the file with the given key * * @param {String} key The storage key * @param {String} storage_class Optional. The storage class. Only required when using transactions * @param {Function} callback Function to call when the delete is complete * @return {Boolean} */ Domain.prototype.del = function(key, storage_class, callback) { if (typeof storage_class == 'function') { callback = storage_class; storage_class = null; } callback = callback || noop; var args = { "key": key, "class": storage_class }; this.mogile.send(this.name, 'DELETE', args, function(err, response) { if (err) { return callback(err); } callback(); }); } /** * Renames a file from one key to another * * @param {String} from_key The original key * @param {String} to_key The new key * @param {Function} callback Function to call when the rename is complete * @return {Boolean} */ Domain.prototype.rename = function(from_key, to_key, callback) { callback = callback || noop; var args = { "from_key": from_key, "to_key": to_key }; this.mogile.send(this.name, 'RENAME', args, function(err, response) { if (err) { return callback(err); } callback(); }); } /** * Gets the file with the given key, and writes it to a local file * * @param {String} key The storage key * @param {String} local The location to write the file to * @param {Function} callback Function to call when the local file has been written. Receives the number of bytes read. * @return {Boolean} */ Domain.prototype.getFile = function(key, local, callback) { callback = callback || noop; var bytes_written = 0; var paused = false; var response = null; this.getPaths(key, 0, function(err, paths) { if (err) { return callback(err); } var write_options = { flags: 'w+', mode: 0666 }; var stream = fs.createWriteStream(local, write_options); stream.on('open', function(fd) { var url_parts = url.parse(paths[0]); var get_options = { host: url_parts.hostname, port: url_parts.port, path: url_parts.pathname }; var get = http.get(get_options, function(res) { response = res; res.on('data', function(data) { bytes_written += data.length; var drained = stream.write(data); if (!drained) { res.pause(); paused = true; } }); res.on('end', function() { var finished = function() { if (paused) { process.nextTick(finished); } else { stream.end(); return callback(null, bytes_written); } } finished(); }); }); get.on('error', function(e) { stream.end(); return callback(e); }); }); stream.on('error', function(e) { return callback(e); }); stream.on('drain', function() { if (paused) { if (!response.complete) response.resume(); paused = false; } }); }); return true; } /** * Stores a file with the given key, in the given storage class, from the local file * * @param {String} key The storage key to save the file as * @param {String} storage_class The storage class * @param {String} local The local file to read from * @param {Function} callback Function to call when the operation is complete. Receives the number of bytes stored. * @return {Boolean} */ Domain.prototype.storeFile = function(key, storage_class, local, callback) { callback = callback || noop; var $this = this; var args = { "key": key, "class": storage_class }; $this.mogile.send($this.name, 'CREATE_OPEN', args, function(err, response) { if (err) { return callback(err); } // Typical response: { devid: '95', fid: '504917521', path: 'http://127.0.0.1:7500/dev95/0/504/917/0504917521.fid' } fs.stat(local, function(err, stat) { if (err) { return callback(err); } var path = url.parse(response.path); var options = { "host": path.hostname, "port": parseFloat(path.port), "path": path.pathname, "method": "PUT", "headers": { "Content-Length": stat.size } }; var request = http.request(options); request.on('error', function(err) { return callback(err); }); var stream = fs.createReadStream(local, { bufferSize: 512 * 1024 }); stream.pipe(request); stream.on('end', function() { request.end(); var args = { "key": key, "class": storage_class, "devid": response.devid, "fid": response.fid, "path": response.path }; $this.mogile.send($this.name, 'CREATE_CLOSE', args, function(err, response) { if (err) { return callback(err); } callback(null, stat.size); }); }); }); }); } /** * Stores a String with the given key, in the given storage class, from the input string * * @param {String} key The storage key to save the file as * @param {String} storage_class The storage class * @param {String} data the string data you want to store * @param {Function} callback Function to call when the operation is complete. Receives the number of bytes stored. * @return {Boolean} */ Domain.prototype.storeData = function(key, storage_class, data, callback) { callback = callback || noop; var $this = this; var args = { "key": key, "class": storage_class }; $this.mogile.send($this.name, 'CREATE_OPEN', args, function(err, response) { if (err) { return callback(err); } // Typical response: { devid: '95', fid: '504917521', path: 'http://127.0.0.1:7500/dev95/0/504/917/0504917521.fid' } var path = url.parse(response.path); var options = { "host": path.hostname, "port": parseFloat(path.port), "path": path.pathname, "method": "PUT", "headers": { "Content-Length": Buffer.byteLength(data) } }; var request = http.request(options); request.on('error', function(err) { return callback(err); }); var stream = streamifier.createReadStream(data); stream.pipe(request); stream.on('end', function() { request.end(); var args = { "key": key, "class": storage_class, "devid": response.devid, "fid": response.fid, "path": response.path }; $this.mogile.send($this.name, 'CREATE_CLOSE', args, function(err, response) { if (err) { return callback(err); } return callback(null, Buffer.byteLength(data)); }); }); }); } // Export the Domain class module.exports = Domain; \ No newline at end of file diff --git a/test/domain.js b/test/domain.js index c452aa5..70b9300 100644 --- a/test/domain.js +++ b/test/domain.js @@ -3,9 +3,9 @@ var mogile = require('../index'); module.exports = testCase({ setUp: function(callback) { - this.trackers = ['mogtracker1:7001']; + this.trackers = ['127.0.0.1:7001']; this.client = mogile.createClient(this.trackers); - this.domain = this.client.domain('default'); + this.domain = this.client.domain('articles'); callback(); }, testGetDomains: function(test) { @@ -15,7 +15,7 @@ module.exports = testCase({ }); }, testStoreFile: function(test) { - this.domain.storeFile('AAAAAAA.jpg', 'dropbox', '/tmp/AAAAAAA.jpg', function(err, bytes_written) { + this.domain.storeFile('asdfdgahh', 'level1', '/home/bluehawky/mogileFs_note.txt', function(err, bytes_written) { if (err) { console.log(err); test.ok(false); @@ -26,7 +26,7 @@ module.exports = testCase({ }); }, testGetPaths: function(test) { - this.domain.getPaths('AAAAAAA.jpg', 0, function(err, paths) { + this.domain.getPaths('asdfdgahh', 0, function(err, paths) { if (err) { test.ok(false); } else { @@ -36,7 +36,7 @@ module.exports = testCase({ }); }, testGetFile: function(test) { - this.domain.getFile('AAAAAAA.jpg', '/tmp/AAAAAAA.jpg', function(err, bytes) { + this.domain.getFile('asdfdgahh', '/home/bluehawky/mogileFs_note_heh.txt', function(err, bytes) { if (err) { test.ok(false); } else { @@ -46,7 +46,7 @@ module.exports = testCase({ }); }, testRenameFile: function(test) { - this.domain.rename('AAAAAAA.jpg', 'BBBBBBB.jpg', function(err) { + this.domain.rename('asdfdgahh', 'zzzzzzzz', function(err) { if (err) { test.ok(false); } else { @@ -57,13 +57,13 @@ module.exports = testCase({ }, testDeleteFile: function(test) { var $this = this; - this.domain.del('BBBBBBB.jpg', function(err) { + this.domain.del('zzzzzzzz', function(err) { if (err) { test.ok(false); } else { test.ok(true); } - $this.domain.getPaths('BBBBBBB.jpg', 0, function(err, paths) { + $this.domain.getPaths('zzzzzzzz', 0, function(err, paths) { if (!err) { test.ok(false); } else if (err.indexOf(err, 'unknown_key') != -1) { @@ -72,5 +72,16 @@ module.exports = testCase({ test.done(); }); }); - } + }, + testStoreData: function(test){ + this.domain.storeData('adfghjkl;z\'','level1','hhhhhhhh把这个东西存到mogilefs中去', function(err, bytes_written) { + if (err) { + console.log(err); + test.ok(false); + } else { + test.ok(bytes_written > 0); + } + test.done(); + }); + } }); \ No newline at end of file