mirror of
https://github.com/mickael-kerjean/filestash.git
synced 2025-11-02 11:57:04 +08:00
172 lines
5.1 KiB
JavaScript
172 lines
5.1 KiB
JavaScript
"use strict";
|
|
|
|
function Data(){
|
|
this.FILE_PATH = "file_path";
|
|
this.FILE_CONTENT = "file_content";
|
|
this.db = null;
|
|
this._init();
|
|
}
|
|
|
|
Data.prototype._init = function(){
|
|
const request = window.indexedDB.open('nuage', 1);
|
|
request.onupgradeneeded = (e) => this._setup(e.target.result);
|
|
|
|
this.db = new Promise((done, err) => {
|
|
request.onsuccess = (e) => {
|
|
done(e.target.result);
|
|
}
|
|
request.onerror = (e) => {
|
|
err(e);
|
|
};
|
|
});
|
|
}
|
|
|
|
Data.prototype._setup = function(db){
|
|
let store;
|
|
if(!db.objectStoreNames.contains(this.FILE_PATH)){
|
|
store = db.createObjectStore(this.FILE_PATH, {keyPath: "path"});
|
|
}
|
|
|
|
if(!db.objectStoreNames.contains(this.FILE_CONTENT)){
|
|
store = db.createObjectStore(this.FILE_CONTENT, {keyPath: "path"});
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Fetch a record using its path, can be whether a file path or content
|
|
*/
|
|
Data.prototype.get = function(type, path){
|
|
if(type !== this.FILE_PATH && type !== this.FILE_CONTENT) return Promise.reject({});
|
|
|
|
return this.db.then((db) => {
|
|
const tx = db.transaction(type, "readonly");
|
|
const store = tx.objectStore(type);
|
|
const query = store.get(path);
|
|
return new Promise((done, error) => {
|
|
query.onsuccess = (e) => {
|
|
let data = query.result;
|
|
done(query.result || null);
|
|
};
|
|
query.onerror = error;
|
|
});
|
|
});
|
|
}
|
|
|
|
Data.prototype.update = function(type, path, fn, exact = true){
|
|
return this.db.then((db) => {
|
|
const tx = db.transaction(type, "readwrite");
|
|
const store = tx.objectStore(type);
|
|
const range = exact === true? IDBKeyRange.only(path) : IDBKeyRange.bound(
|
|
path,
|
|
path+'\uFFFF',
|
|
false, true
|
|
);
|
|
const request = store.openCursor(range);
|
|
let new_data = null;
|
|
return new Promise((done, err) => {
|
|
request.onsuccess = function(event) {
|
|
const cursor = event.target.result;
|
|
if(!cursor) return done(new_data);
|
|
new_data = fn(cursor.value || null);
|
|
cursor.delete(cursor.value.path);
|
|
store.put(new_data);
|
|
cursor.continue();
|
|
};
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
Data.prototype.upsert = function(type, path, fn){
|
|
return this.db.then((db) => {
|
|
const tx = db.transaction(type, "readwrite");
|
|
const store = tx.objectStore(type);
|
|
const query = store.get(path);
|
|
return new Promise((done, error) => {
|
|
query.onsuccess = (e) => {
|
|
const new_data = fn(query.result || null);
|
|
if(!new_data) return done(query.result || null);
|
|
|
|
const request = store.put(new_data);
|
|
request.onsuccess = () => done(new_data);
|
|
request.onerror = (e) => error(e);
|
|
};
|
|
query.onerror = error;
|
|
});
|
|
});
|
|
}
|
|
|
|
Data.prototype.add = function(type, path, data){
|
|
if(type !== this.FILE_PATH && type !== this.FILE_CONTENT) return Promise.reject({});
|
|
|
|
return this.db.then((db) => {
|
|
return new Promise((done, error) => {
|
|
const tx = db.transaction(type, "readwrite");
|
|
const store = tx.objectStore(type);
|
|
const request = store.put(data);
|
|
request.onsuccess = () => done(data);
|
|
request.onerror = (e) => error(e);
|
|
});
|
|
});
|
|
}
|
|
|
|
Data.prototype.remove = function(type, path, exact = true){
|
|
return this.db.then((db) => {
|
|
const tx = db.transaction(type, "readwrite");
|
|
const store = tx.objectStore(type);
|
|
|
|
if(exact === true){
|
|
const req = store.delete(path);
|
|
return new Promise((done, err) => {
|
|
req.onsuccess = () => done();
|
|
req.onerror = err;
|
|
});
|
|
}else{
|
|
const request = store.openCursor(IDBKeyRange.bound(
|
|
path,
|
|
path+'\uFFFF',
|
|
true, true
|
|
));
|
|
return new Promise((done, err) => {
|
|
request.onsuccess = function(event) {
|
|
const cursor = event.target.result;
|
|
if(cursor){
|
|
cursor.delete(cursor.value.path);
|
|
cursor.continue();
|
|
}else{
|
|
done();
|
|
}
|
|
};
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
Data.prototype.fetchAll = function(fn, type = this.FILE_PATH){
|
|
return this.db.then((db) => {
|
|
const tx = db.transaction(type, "readwrite");
|
|
const store = tx.objectStore(type);
|
|
const request = store.openCursor();
|
|
|
|
return new Promise((done, error) => {
|
|
request.onsuccess = function(event) {
|
|
const cursor = event.target.result;
|
|
if(!cursor) return done();
|
|
const new_value = fn(cursor.value);
|
|
cursor.continue();
|
|
};
|
|
});
|
|
});
|
|
}
|
|
|
|
Data.prototype.destroy = function(){
|
|
this.db.then((db) => db.close())
|
|
clearTimeout(this.intervalId);
|
|
window.indexedDB.deleteDatabase('nuage');
|
|
this._init();
|
|
}
|
|
|
|
|
|
export const cache = new Data();
|
|
window._cache = cache;
|