LokiDB
LokiDB copied to clipboard
Any release date for a non beta version available?
I can't wait any longer. 😸
Thank you for your enthusiasm. :)
I will write down a roadmap to better schedule a release date.
Hi !
In this roadmap, does a handover from LokiJS to LokiJS2 is planned ? Right now, it feels like no one is really in-knows of this repo :/
A hint on LokiJS product page or a post on echojs would probably change this. It seems the creators of this repo do not want a public state at this time.
I understand, however, this place a problem where we can't use this even in our proto, because in term of rules, we can't use a npm with so few download, I think that publicly advise it would allow more bug reports if existing, more feature too if needed, but the more people test this repo, the best it is, isn't it ?
We were able to make all our tests passing, so as far as I know, it works great, but yeah, we could use a beta-5.0.0, but definitively not with so few usage :/
(P.S : I'm just sharing our personal story here, I absolutely do not push to anything as I couldn't follow the last discussion on this repo, I'm not sure of the whole status, but I feel usage feedback could have it's usage in this discussion)
I would like to know an estimation for a stable version. should I start with lokijs 1.x and migrate to 2, or start with beta waiting a release date?
We have no release date yet.
I would suggest starting with LokiJS 1. The serialization of LokiDB 2 beta will not be supported after the release. But there will be a migration path from LokiJS 1 to 2.
@Viatorus will this also be true for those using lokijs in cordova/ionic projects that utilize the LokiCordovaFSAdapter?
@greaterking Yes, after someone has converted the LokiCordovaFSAdapter to LokiDB/Typescript.
Have @greaterking or @Viatorus either of you used this in Cordova since Sept? Did you use the CordovaFSAdapter and how did it go so far?
@Mapiac I'm using Ionic4 which uses cordova, though everything is written in typescript. I had to port the FSAdapter over for ionic everything is pretty much the same but had to make all methods return as a promise. I did run into an issue with the saveDatabase() method which for some reason kept returning dbname as undefined when used with initializePersistence()
loki-ionic-fs-adapter.ts
import { StorageAdapter } from '@lokidb/loki/types/common/types';
const TAG = '[LokiIonicFSAdapter]';
declare var window: any;
declare var cordova: any;
class LokiIonicFSAdapterError extends Error {}
export class LokiIonicFsAdapter implements StorageAdapter {
private options: any;
constructor() {
this.options = {'prefix': 'loki'};
}
loadDatabase(dbname: string): Promise<any> {
const self = this;
return new Promise(function (resolve, reject) {
self._getFile(dbname,
(fileEntry) => {
fileEntry.file((file) => {
const reader: FileReader = new FileReader();
reader.onloadend = (event: any) => {
const contents: any = event.target.result;
if (contents.length === 0) {
console.log(TAG, 'database is empty');
resolve('[]');
} else {
console.log('sending back database');
resolve(contents);
}
};
reader.readAsText(file);
}, (err) => {
console.log(TAG, 'error reading file', err);
reject(new LokiIonicFSAdapterError('Unable to read file' + err.message));
});
},
(err) => {
console.log(TAG, 'error getting file', err);
reject(new LokiIonicFSAdapterError('Unable to get file: ' + err.message));
}
);
});
}
saveDatabase(dbname: string, serialization: string): Promise<void> {
console.log('SAVNIG TO: ' + dbname); // --> dbname always blank for me :/ <--
const self = this;
return new Promise(function(resolve, reject){
self._getFile(dbname,
(fileEntry) => {
fileEntry.createWriter(
(fileWriter) => {
fileWriter.onwriteend = () => {
if (fileWriter.length === 0) {
const blob: any = self._createBlob(serialization, 'text/plain');
resolve(fileWriter.write(blob));
}
};
fileWriter.truncate(0);
},
(err) => {
//console.log(TAG, 'error writing file', err)
reject(new LokiIonicFSAdapterError('Unable to write file' + JSON.stringify(err)));
}
);
},
(err) => {
//console.log(TAG, 'error getting file', err)
reject(new LokiIonicFSAdapterError('Unable to get file' + JSON.stringify(err)));
}
);
});
}
deleteDatabase(dbname: string): Promise<void> {
const self = this;
return new Promise(function(resolve, reject){
window.resolveLocalFileSystemURL(cordova.file.dataDirectory,
(dir) => {
const fileName: string = self.options.prefix + '__' + dbname;
dir.getFile(fileName, {create: true},
(fileEntry) => {
fileEntry.remove(
() => {
resolve();
},
(err) => {
// console.log(TAG, 'error delete file', err)
reject( new LokiIonicFSAdapterError('Unable to delete file' + JSON.stringify(err)));
}
);
},
(err) => {
// console.log(TAG, 'error delete database', err)
reject( new LokiIonicFSAdapterError(
'Unable to delete database' + JSON.stringify(err)
));
}
);
},
(err) => {
// console.log(TAG, 'Unable to resolve local file system URL', err)
reject( new LokiIonicFSAdapterError(
'Unable to resolve local file system URL' + JSON.stringify(err)
));
}
);
});
}
private _getFile(name: string, handleSuccess: any, handleError: any): void {
// console.log(TAG, 'Retrieving file: ' + name)
window.resolveLocalFileSystemURL(cordova.file.dataDirectory,
(dir) => {
const fileName: string = this.options.prefix + '__' + name;
dir.getFile(fileName, {create: true}, handleSuccess, handleError);
},
(err) => {
console.error(
'Unable to resolve local file system URL' + JSON.stringify(err)
);
}
);
}
// adapted from http://stackoverflow.com/questions/15293694/blob-constructor-browser-compatibility
private _createBlob(data: string, datatype: string): any {
let blob: any;
try {
blob = new Blob([data], {type: datatype});
} catch (err) {
window.BlobBuilder = window.BlobBuilder ||
window.WebKitBlobBuilder ||
window.MozBlobBuilder ||
window.MSBlobBuilder;
if (err.name === 'TypeError' && window.BlobBuilder) {
const bb: MSBlobBuilder = new window.BlobBuilder();
bb.append(data);
blob = bb.getBlob(datatype);
} else if (err.name === 'InvalidStateError') {
// InvalidStateError (tested on FF13 WinXP)
blob = new Blob([data], {type: datatype});
} else {
// We're screwed, blob constructor unsupported entirely
console.error(
'Unable to create blob' + JSON.stringify(err)
);
}
}
return blob;
}
}
Instantiate the db...
import { LokiIonicFsAdapter } from '../loki-adapter/loki-ionic-fs-adapter';
let db = new Loki('my.db');
db.initializePersistence({
adapter: new LokiIonicFsAdapter,
autoload: true //the data base will auto/load just fine
}).then((e) => {
// do your db stuff or other set up here...
});
...but when saving which uses this interface from the adapter saveDatabase(dbname: string, serialization: string): Promise<void>
dbname
is always undefined. To make this work I ended having to set it explicitly by setting db.filename
in then method of the db.initializePersistence()
promise
Hope this helps.
@greaterking that's so kind thanks a ton! 6 months on are you pretty happy with Loki?
LokiJS has great momentum going on! Everyone is loving LokiJS > other solutions.
Over the past 6 months it has seen an amazing surge of fans and enthusiasts! Perfect time to announce V2 imo! 🌞
@mesqueeb so far so good...I just wish it was released already. It fits a very specific need for me...not sure why the low activity ..hoping every thing is ok with the authors etc.
I ended up having to make things promise based to make this work properly here is that code *used in ionic
loki-ionic-fs-adapter.ts
import { Injectable } from '@angular/core';
const TAG = '[LokiIonicFSAdapter]';
declare var window: any;
declare var cordova: any;
@Injectable({
providedIn: 'root'
})
class LokiIonicFSAdapterError extends Error {}
export class LokiIonicFsAdapter implements StorageAdapter {
private options: any;
constructor() {
this.options = {'prefix': 'loki'};
}
loadDatabase(dbname: string): Promise<any> {
return new Promise((resolve, reject) => {
this._getFile(dbname,
(fileEntry) => {
fileEntry.file((file) => {
const reader: FileReader = new FileReader();
reader.onloadend = (event: any) => {
const contents: any = event.target.result;
if (contents.length === 0) {
console.log(TAG, 'database is empty');
resolve('[]');
} else {
console.log('sending back database');
resolve(contents);
}
};
reader.readAsText(file);
}, (err) => {
console.log(TAG, 'error reading file', err);
reject(new LokiIonicFSAdapterError('Unable to read file' + err.message));
});
},
(err) => {
console.log(TAG, 'error getting file', err);
reject(new LokiIonicFSAdapterError('Unable to get file: ' + err.message));
}
);
});
}
saveDatabase(dbname: string, serialization: string): Promise<void> {
console.log('SAVNIG TO: ' + dbname);
return new Promise((resolve, reject) =>{
this._getFile(dbname,
(fileEntry) => {
fileEntry.createWriter(
(fileWriter) => {
fileWriter.onwriteend = () => {
if (fileWriter.length === 0) {
const blob: any = this._createBlob(serialization, 'text/plain');
resolve(fileWriter.write(blob));
}
};
fileWriter.truncate(0);
},
(err) => {
//console.log(TAG, 'error writing file', err)
reject(new LokiIonicFSAdapterError('Unable to write file' + JSON.stringify(err)));
}
);
},
(err) => {
//console.log(TAG, 'error getting file', err)
reject(new LokiIonicFSAdapterError('Unable to get file' + JSON.stringify(err)));
}
);
});
}
deleteDatabase(dbname: string): Promise<void> {
return new Promise((resolve, reject) => {
window.resolveLocalFileSystemURL(cordova.file.dataDirectory,
(dir) => {
const fileName: string = this.options.prefix + '__' + dbname;
dir.getFile(fileName, {create: true},
(fileEntry) => {
fileEntry.remove(
() => {
resolve();
},
(err) => {
// console.log(TAG, 'error delete file', err)
reject( new LokiIonicFSAdapterError('Unable to delete file' + JSON.stringify(err)));
}
);
},
(err) => {
// console.log(TAG, 'error delete database', err)
reject( new LokiIonicFSAdapterError(
'Unable to delete database' + JSON.stringify(err)
));
}
);
},
(err) => {
// console.log(TAG, 'Unable to resolve local file system URL', err)
reject( new LokiIonicFSAdapterError(
'Unable to resolve local file system URL' + JSON.stringify(err)
));
}
);
});
}
private _getFile(name: string, handleSuccess: any, handleError: any): void {
window.resolveLocalFileSystemURL(cordova.file.dataDirectory,
(dir) => {
const fileName: string = this.options.prefix + '__' + name;
dir.getFile(fileName, {create: true}, handleSuccess, handleError);
},
(err) => {
console.error(
'Unable to resolve local file system URL' + JSON.stringify(err)
);
}
);
}
// adapted from http://stackoverflow.com/questions/15293694/blob-constructor-browser-compatibility
private _createBlob(data: string, datatype: string): any {
let blob: any;
try {
blob = new Blob([data], {type: datatype});
} catch (err) {
window.BlobBuilder = window.BlobBuilder ||
window.WebKitBlobBuilder ||
window.MozBlobBuilder ||
window.MSBlobBuilder;
if (err.name === 'TypeError' && window.BlobBuilder) {
const bb: MSBlobBuilder = new window.BlobBuilder();
bb.append(data);
blob = bb.getBlob(datatype);
} else if (err.name === 'InvalidStateError') {
// InvalidStateError (tested on FF13 WinXP)
blob = new Blob([data], {type: datatype});
} else {
// We're screwed, blob constructor unsupported entirely
console.error(
'Unable to create blob' + JSON.stringify(err)
);
}
}
return blob;
}
}