Is your feature request related to a problem? Please describe.
I wish to store some information where I believe IsolatedStorage is the best candidate. The dotnet API does not provide a full path for the IsolatedStorage file where we can pass it to LiteDb to store the database (with reflection its possible, however it is a hack and not a perfect solution I believe).
Describe the solution you'd like
I would like a constructor which accepts IsolatedStorageFile instance and with the other options like Password and other connection string options we can pass.
Describe alternatives you've considered
I tried it with the hack and was not satisfied with the flow of the code, for just getting a field, I had to use reflection, and it is internal which may get renamed anytime.
Additional context
I would be happy if there is another constructor overload with the options mentioned above.
Hi
I think it is already possible with IsolatedStorageFileStream and LiteDatabase constructor overload type ILiteEngine implementation.
I was able to ready LiteDB instance from isolate storage and read / insert documents. Below I’m attaching sample code. It can be enhanced to your needs.
class Program
{
static void Main(string[] args)
{
IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForAssembly();
String[] dirNames = isoFile.GetDirectoryNames("*");
if (dirNames.Contains("LiteDB") && isoFile.FileExists("LiteDb\\LiteDb.dll")) {
IsolatedStorageFileStream liteDBStream = isoFile.OpenFile("LiteDb\\LiteDb.dll", System.IO.FileMode.Open);
var connectionType = LiteDB.ConnectionType.Shared;
EngineSettings engineSettings = new EngineSettings();
engineSettings.DataStream = liteDBStream;
engineSettings.Filename = "LiteDb.dll";
engineSettings.Password = "1234";
engineSettings.ReadOnly = false;
ILiteEngine liteDbEngine = connectionType == LiteDB.ConnectionType.Shared ?
(ILiteEngine)new LiteDB.SharedEngine(engineSettings) : (ILiteEngine)new LiteEngine(engineSettings);
LiteDB.LiteDatabase liteDatabase = new LiteDB.LiteDatabase(liteDbEngine);
var testQuery = liteDatabase.GetCollection<TestDto>("query");
testQuery.Insert(new TestDto() { Name = "Worked" } );
var result = testQuery.FindAll();
}
}
}
class TestDto {
public ObjectId Id { get; set; }
public string Name {get;set;}
}
Let me know if this works for you.
Regards
Piotr
@quicksln Your basic idea is good, but your solution lacks some things, like a log stream (if you don't have a FileStream as log stream, there will be data loss in case of a crash). Here's my proposed solution:
```C#
IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForAssembly();
string path = "myfilepath.db"; //replace this with your datafile path
string logPath = path.Replace(".db", "-log.db");
IsolatedStorageFileStream dataStream = isf.OpenFile(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);
IsolatedStorageFileStream logStream = isf.OpenFile(logPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);
EngineSettings settings = new EngineSettings();
settings.DataStream = dataStream;
settings.LogStream = logStream;
settings.ReadOnly = false;
settings.Password = "1234"; //null if no password needed
var connectionType = LiteDB.ConnectionType.Direct; //use this variable to select the connection type
//(Direct is recommended, unless you need multi-process support)
ILiteEngine liteDbEngine = connectionType == LiteDB.ConnectionType.Shared ?
(ILiteEngine)new LiteDB.SharedEngine(settings) : (ILiteEngine)new LiteEngine(settings);
using (LiteDatabase db = new LiteDatabase(liteDbEngine))
{
//do whatever you want here
}
```
@pankaj-nikam
Thank you @quicksln and @lbnascimento :)
The solutions do seem promising. I am wondering if it is good enough to be a feature itself in the package?
Users may find it helpful if it supports isolated storage out of the box.
What do you think?
@lbnascimento good point with adding log file stream, @pankaj-nikam hope you find this useful.
Defiantly it's good candidate for extension method inside individual project :)
Regards
Piotr
Agree with you @quicksln. Its good to make an extension method.
@quicksln It's a possibility, but I'd have to think of a better way to integrate this feature in LiteDB. Maybe adding a log stream parameter in the constructor would be good enough (and it would also be very flexible).
@lbnascimento Agree that could be more helpful and complete solution. What I would like to avoid is to introduce new Ctor. Taking you suggestion I think good candidate for extension is :
public LiteDatabase(Stream stream, BsonMapper mapper = null)
{
var settings = new EngineSettings
{
DataStream = stream ?? throw new ArgumentNullException(nameof(stream))
};
…
}
to replace it with
public LiteDatabase(Stream stream, BsonMapper mapper = null, Stream logStream = null)
{
var settings = new EngineSettings
{
DataStream = stream ?? throw new ArgumentNullException(nameof(stream)),
LogStream = logStream
};
@lbnascimento let me know what you think, I'll create PR to implement this.
@quicksln Yes, somethink like that would be fine. And, if possible, please make some tests for it, just to make sure everything is working as expected (you can use TempStream).