Skip to content
Browse files

Enable persistent saving of memory stores.

  • Loading branch information...
1 parent bb37f11 commit 0dc818d7643b6b9cb7a123d59d979ce68423ff1a @creationix committed Feb 25, 2010
Showing with 81 additions and 12 deletions.
  1. +78 −10 lib/persistence/memory.js
  2. +3 −2 test/common.js
View
88 lib/persistence/memory.js
@@ -1,4 +1,5 @@
var sys = require('sys');
+var fs = require('fs');
var defer = process.nextTick;
function make_row(id, data) {
@@ -8,10 +9,16 @@ function make_row(id, data) {
return row;
}
-function Store(conn, columns) {
- this.conn = conn;
+function Store(conn, name, columns) {
this.columns = columns;
- this.data = [];
+ this.changed = conn.changed;
+ // Hook up with the main data store
+ if (!conn.data[name]) {
+ conn.data[name] = [];
+ conn.changed();
+ }
+ this.data = conn.data[name];
+
}
Store.prototype = {
get: function (id, callback) {
@@ -113,6 +120,7 @@ Store.prototype = {
},
save: function (row, callback) {
var table = this.data;
+ var self = this;
defer(function () {
var data = {},
id = table.length + 1;
@@ -121,16 +129,19 @@ Store.prototype = {
id = data._id;
delete data._id;
table[id - 1] = data;
+ self.changed();
callback();
} else {
table.push(data);
row._id = table.length;
+ self.changed();
callback(row._id);
}
});
},
remove: function (row, callback) {
var table = this.data;
+ var self = this;
defer(function () {
var index;
if (row instanceof Object) {
@@ -140,30 +151,87 @@ Store.prototype = {
index = row - 1;
}
table.splice(index, 1);
+ self.changed();
callback();
});
},
nuke: function (callback) {
var self = this;
defer(function () {
self.data = [];
+ self.changed();
callback();
});
}
};
-function Connection() {}
+function Connection(file) {
+ var data = this.data = {};
+ var waiting = false;
+ var one_more = false;
+ var self = this;
+
+ // Save at most often evert 5 seconds.
+ var timer;
+ function changed() {
+ if (waiting) {
+ one_more = true;
+ } else {
+ save();
+ waiting = true;
+ timer = setTimeout(function () {
+ waiting = false;
+ if (one_more) {
+ one_more = false;
+ changed();
+ }
+ }, 30000); // 30 second rest between writes
+ }
+ }
+
+ function save() {
+ if (timer) { clearTimeout(timer); }
+ var json = JSON.stringify(data)
+ fs.writeFile(file, json, function (err) {
+ if (err) {
+ self.emit('error', err);
+ // sys.error(err);
+ } else {
+ // sys.puts("Saved " + json.length + " bytes to " + file);
+ }
+ });
+ }
+
+ function load() {
+ fs.readFile(file, function (err, json) {
+ if (err) {
+ // sys.error("Warning: cannot open " + file);
+ save(); // Trigger File creation
+ } else {
+ // sys.puts("Loaded " + json.length + " bytes from " + file);
+ self.data = JSON.parse(json);
+ }
+ })
+ }
+
+ if (file) {
+ load();
+ this.changed = changed;
+ this.close = save;
+ }
+}
Connection.prototype = new process.EventEmitter();
-Connection.prototype.get_store = function (columns) {
- return new Store(this, columns);
+Connection.prototype.get_store = function (name, columns) {
+ return new Store(this, name, columns);
};
Connection.prototype.close = function () {};
+Connection.prototype.changed = function () {};
-exports.get_store = function (columns) {
- return (new Connection).get_store(columns);
+exports.get_store = function (name, columns) {
+ return (new Connection).get_store(name, columns);
};
-exports.new_connection = function () {
- var db = new Connection();
+exports.new_connection = function (file) {
+ var db = new Connection(file);
defer(function () {
db.emit('connection');
});
View
5 test/common.js
@@ -31,15 +31,16 @@ exports.configs = {
username: "test",
password: "password"
},
- memory: "/tmp/test"
+ memory: "/tmp/test.json"
};
// Alias process.nextTick
var defer = exports.defer = process.nextTick;
var before_execs = {
postgres: "/usr/local/bin/dropdb " + exports.configs.postgres.database + "; /usr/local/bin/createdb -O " + exports.configs.postgres.username + " " + exports.configs.postgres.database,
- sqlite: "rm -f " + exports.configs.sqlite
+ sqlite: "rm -f " + exports.configs.sqlite,
+ memory: "rm -f " + exports.configs.memory
}
// Call these before each test to clean the slate

0 comments on commit 0dc818d

Please sign in to comment.
Something went wrong with that request. Please try again.