Skip to content

Commit ec2e523

Browse files
authored
feat(fs-storage): add fs storage as separate package (#19)
1 parent 548abfe commit ec2e523

File tree

6 files changed

+180
-1
lines changed

6 files changed

+180
-1
lines changed

CONTRIBUTING.md

+1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ The following is the list of supported scopes:
138138
* **loki**: The LokiJS database.
139139
* **partitioning-adapter**: The partitioning adapter.
140140
* **local-storage**: The local storage adapter.
141+
* **fs-storage**: The file system storage adapter.
141142
* **fts**: A full text search for the database.
142143

143144
There are currently a few exceptions to the "use package name" rule:

config/build.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ const conventionalChangelog = require("conventional-changelog");
1010
const PACKAGES = [
1111
"loki",
1212
"partitioning-adapter",
13-
"local-storage"
13+
"local-storage",
14+
"fs-storage"
1415
];
1516

1617
const ROOT_DIR = process.cwd();

packages/fs-storage/package.json

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "@lokijs/fs-storage",
3+
"description": "A persistence adapter which persists to node fs module storage.",
4+
"author": "Various authors",
5+
"license": "MIT",
6+
"repository": {
7+
"type": "git",
8+
"url": "https://github.com/LokiJS-Forge/LokiJS2.git"
9+
},
10+
"main": "lokijs.fs-storage.js",
11+
"dependencies": {
12+
"@lokijs/loki": "0"
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/* global describe, it, expect */
2+
import {Loki} from "../../../loki/src/loki";
3+
import {LokiFSStorage} from "../../src/fs_storage";
4+
5+
describe("testing persistence adapter", function () {
6+
it("LokiFSStorage", function (done) {
7+
const db = new Loki("myTestApp");
8+
9+
const adapter = {adapter: new LokiFSStorage()};
10+
db.initializePersistence(adapter)
11+
.then(() => {
12+
db.addCollection("myColl").insert({name: "Hello World"});
13+
return db.saveDatabase().then(() => {
14+
const db2 = new Loki("myTestApp");
15+
return db2.initializePersistence(adapter)
16+
.then(() => {
17+
return db2.loadDatabase()
18+
.then(() => {
19+
expect(db2.getCollection("myColl").find()[0].name).toEqual("Hello World");
20+
});
21+
});
22+
});
23+
})
24+
.then(() => {
25+
const db3 = new Loki("other");
26+
return db3.initializePersistence(adapter)
27+
.then(() => {
28+
return db3.loadDatabase()
29+
.then(() => {
30+
expect(false).toEqual(true);
31+
}, () => {
32+
expect(true).toEqual(true);
33+
});
34+
});
35+
})
36+
.then(() => {
37+
return db.deleteDatabase();
38+
})
39+
.then(() => {
40+
return db.loadDatabase()
41+
.then(() => {
42+
expect(db.getCollection("myColl").find()[0].name).toEqual("Hello World");
43+
expect(false).toEqual(true);
44+
done();
45+
}, () => {
46+
expect(true).toEqual(true);
47+
done();
48+
});
49+
});
50+
});
51+
});

packages/fs-storage/src/fs_storage.js

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import {Loki} from "../../loki/src/loki";
2+
import fs from "fs";
3+
4+
/**
5+
* A loki persistence adapter which persists using node fs module.
6+
*/
7+
export class LokiFSStorage {
8+
/**
9+
* loadDatabase() - Load data from file, will throw an error if the file does not exist
10+
* @param {string} dbname - the filename of the database to load
11+
* @returns {Promise} a Promise that resolves after the database was loaded
12+
* @memberof LokiFsAdapter
13+
*/
14+
loadDatabase(dbname) {
15+
return new Promise((resolve, reject) => {
16+
fs.stat(dbname, (err, stats) => {
17+
if (!err && stats.isFile()) {
18+
fs.readFile(dbname, {
19+
encoding: "utf8"
20+
}, function readFileCallback(err, data) {
21+
if (err) {
22+
reject(err);
23+
} else {
24+
resolve(data);
25+
}
26+
});
27+
} else {
28+
reject();
29+
}
30+
});
31+
});
32+
}
33+
34+
/**
35+
* saveDatabase() - save data to file, will throw an error if the file can't be saved
36+
* might want to expand this to avoid dataloss on partial save
37+
* @param {string} dbname - the filename of the database to load
38+
* @returns {Promise} a Promise that resolves after the database was persisted
39+
* @memberof LokiFsAdapter
40+
*/
41+
saveDatabase(dbname, dbstring) {
42+
const tmpdbname = dbname + "~";
43+
44+
return new Promise((resolve, reject) => {
45+
fs.writeFile(tmpdbname, dbstring, (err) => {
46+
if (err) {
47+
reject(err);
48+
} else {
49+
fs.rename(tmpdbname, dbname, (err) => {
50+
if (err) {
51+
reject(err);
52+
} else {
53+
resolve();
54+
}
55+
});
56+
}
57+
});
58+
});
59+
}
60+
61+
/**
62+
* deleteDatabase() - delete the database file, will throw an error if the
63+
* file can't be deleted
64+
* @param {string} dbname - the filename of the database to delete
65+
* @returns {Promise} a Promise that resolves after the database was deleted
66+
* @memberof LokiFsAdapter
67+
*/
68+
deleteDatabase(dbname) {
69+
return new Promise((resolve, reject) => {
70+
fs.unlink(dbname, function deleteDatabaseCallback(err) {
71+
if (err) {
72+
reject(err);
73+
} else {
74+
resolve();
75+
}
76+
});
77+
});
78+
}
79+
}
80+
81+
Loki.LokiFSStorage = LokiFSStorage;
82+
83+
export default LokiFSStorage;

packages/fs-storage/webpack.config.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/* global __dirname, module, require */
2+
const path = require("path");
3+
4+
module.exports = {
5+
devtool: "source-map",
6+
entry: path.join(__dirname, "src", "fs_storage.js"),
7+
output: {
8+
filename: "lokijs.fs-storage.js",
9+
library: "@lokijs/fs-storage",
10+
libraryTarget: "umd2",
11+
umdNamedDefine: false
12+
},
13+
externals: {
14+
"../../loki/src/loki": "@lokijs/loki",
15+
"fs": "fs"
16+
},
17+
module: {
18+
loaders: [
19+
{
20+
test: /(\.js)$/,
21+
loader: "eslint-loader",
22+
exclude: /(node_modules|bower_components)/,
23+
options: {
24+
configFile: path.join("config", "eslintrc.js")
25+
}
26+
}
27+
]
28+
}
29+
};

0 commit comments

Comments
 (0)