|
|
@ -5,7 +5,6 @@ |
|
|
|
var fs = require('fs') |
|
|
|
var fs = require('fs') |
|
|
|
, path = require('path') |
|
|
|
, path = require('path') |
|
|
|
, model = require('./model') |
|
|
|
, model = require('./model') |
|
|
|
, customUtils = require('./customUtils') |
|
|
|
|
|
|
|
, async = require('async') |
|
|
|
, async = require('async') |
|
|
|
, mkdirp = require('mkdirp') |
|
|
|
, mkdirp = require('mkdirp') |
|
|
|
; |
|
|
|
; |
|
|
@ -14,9 +13,18 @@ var fs = require('fs') |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Create a new Persistence object for database options.db |
|
|
|
* Create a new Persistence object for database options.db |
|
|
|
* @param {Datastore} options.db |
|
|
|
* @param {Datastore} options.db |
|
|
|
|
|
|
|
* @param {Boolean} options.nodeWebkitAppName Optional, specify the name of your NW app if you want options.filename to be relative to the directory where |
|
|
|
|
|
|
|
* Node Webkit stores application data such as cookies and local storage (the best place to store data in my opinion) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
function Persistence (options) { |
|
|
|
function Persistence (options) { |
|
|
|
this.db = options.db; |
|
|
|
this.db = options.db; |
|
|
|
|
|
|
|
this.inMemoryOnly = this.db.inMemoryOnly; |
|
|
|
|
|
|
|
this.filename = this.db.filename; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// For NW apps, store data in the same directory where NW stores application data
|
|
|
|
|
|
|
|
if (this.filename && options.nodeWebkitAppName) { |
|
|
|
|
|
|
|
this.filename = Persistence.getNWAppFilename(options.nodeWebkitAppName, this.filename); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -32,6 +40,39 @@ Persistence.ensureDirectoryExists = function (dir, cb) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Return the path the datafile if the given filename is relative to the directory where Node Webkit stores |
|
|
|
|
|
|
|
* data for this application. Probably the best place to store data |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
Persistence.getNWAppFilename = function (appName, relativeFilename) { |
|
|
|
|
|
|
|
var home; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (process.platform) { |
|
|
|
|
|
|
|
case 'win32': |
|
|
|
|
|
|
|
case 'win64': |
|
|
|
|
|
|
|
home = process.env.LOCALAPPDATA || process.env.APPDATA; |
|
|
|
|
|
|
|
if (!home) { throw "Couldn't find the base application data folder"; } |
|
|
|
|
|
|
|
home = path.join(home, appName); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 'darwin': |
|
|
|
|
|
|
|
home = process.env.HOME; |
|
|
|
|
|
|
|
if (!home) { throw "Couldn't find the base application data directory"; } |
|
|
|
|
|
|
|
home = path.join(home, 'Library', 'Application Support', appName); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 'linux': |
|
|
|
|
|
|
|
home = process.env.HOME; |
|
|
|
|
|
|
|
if (!home) { throw "Couldn't find the base application data directory"; } |
|
|
|
|
|
|
|
home = path.join(home, '.config', appName); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
throw "Can't use the Node Webkit relative path for platform " + process.platform; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return path.join(home, 'nedb-data', relativeFilename); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Persist cached database |
|
|
|
* Persist cached database |
|
|
|
* This serves as a compaction function since the cache always contains only the number of documents in the collection |
|
|
|
* This serves as a compaction function since the cache always contains only the number of documents in the collection |
|
|
@ -49,7 +90,7 @@ Persistence.prototype.persistCachedDatabase = function (cb) { |
|
|
|
|
|
|
|
|
|
|
|
if (toPersist.length === 0) { return callback(null); } |
|
|
|
if (toPersist.length === 0) { return callback(null); } |
|
|
|
|
|
|
|
|
|
|
|
fs.writeFile(this.db.filename, toPersist, function (err) { return callback(err); }); |
|
|
|
fs.writeFile(this.filename, toPersist, function (err) { return callback(err); }); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -66,7 +107,7 @@ Persistence.prototype.persistNewState = function (newDocs, cb) { |
|
|
|
; |
|
|
|
; |
|
|
|
|
|
|
|
|
|
|
|
// In-memory only datastore
|
|
|
|
// In-memory only datastore
|
|
|
|
if (self.db.inMemoryOnly) { return callback(null); } |
|
|
|
if (self.inMemoryOnly) { return callback(null); } |
|
|
|
|
|
|
|
|
|
|
|
self.db.datafileSize += newDocs.length; |
|
|
|
self.db.datafileSize += newDocs.length; |
|
|
|
|
|
|
|
|
|
|
@ -76,7 +117,7 @@ Persistence.prototype.persistNewState = function (newDocs, cb) { |
|
|
|
|
|
|
|
|
|
|
|
if (toPersist.length === 0) { return callback(null); } |
|
|
|
if (toPersist.length === 0) { return callback(null); } |
|
|
|
|
|
|
|
|
|
|
|
fs.appendFile(self.db.filename, toPersist, 'utf8', function (err) { |
|
|
|
fs.appendFile(self.filename, toPersist, 'utf8', function (err) { |
|
|
|
return callback(err); |
|
|
|
return callback(err); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}; |
|
|
|
}; |
|
|
@ -134,15 +175,15 @@ Persistence.prototype._loadDatabase = function (cb) { |
|
|
|
self.db.datafileSize = 0; |
|
|
|
self.db.datafileSize = 0; |
|
|
|
|
|
|
|
|
|
|
|
// In-memory only datastore
|
|
|
|
// In-memory only datastore
|
|
|
|
if (self.db.inMemoryOnly) { return callback(null); } |
|
|
|
if (self.inMemoryOnly) { return callback(null); } |
|
|
|
|
|
|
|
|
|
|
|
async.waterfall([ |
|
|
|
async.waterfall([ |
|
|
|
function (cb) { |
|
|
|
function (cb) { |
|
|
|
Persistence.ensureDirectoryExists(path.dirname(self.db.filename), function (err) { |
|
|
|
Persistence.ensureDirectoryExists(path.dirname(self.filename), function (err) { |
|
|
|
fs.exists(self.db.filename, function (exists) { |
|
|
|
fs.exists(self.filename, function (exists) { |
|
|
|
if (!exists) { return fs.writeFile(self.db.filename, '', 'utf8', function (err) { cb(err); }); } |
|
|
|
if (!exists) { return fs.writeFile(self.filename, '', 'utf8', function (err) { cb(err); }); } |
|
|
|
|
|
|
|
|
|
|
|
fs.readFile(self.db.filename, 'utf8', function (err, rawData) { |
|
|
|
fs.readFile(self.filename, 'utf8', function (err, rawData) { |
|
|
|
if (err) { return cb(err); } |
|
|
|
if (err) { return cb(err); } |
|
|
|
var treatedData = Persistence.treatRawData(rawData); |
|
|
|
var treatedData = Persistence.treatRawData(rawData); |
|
|
|
|
|
|
|
|
|
|
|