11

I'm currently working on some evaluation work for a project that I'm planning.

I recently looked at solutions for a data storage mechanism for my application and while researching stumbled upon SQLite. I currently use SQLite with the System.Data.SQLite wrapper.

I really like the way it works but I have one problem with it that I couldn't get fixed and I also found no help concerning my problem on the internet.

I would like my SQLite Database to be embedded into one of my applications DLLs (ie. Title.Storage.dll) to be used within this DLL. Is this possible?

How can I access the database then?

It would be great if I could use something like:

SQLiteConnection con = new SQLiteConnection();
con.ConnectionString="DataSource=Title.Storage.storage.db3";
con.Open();

Thanks in advance and best regards,

3Fox

chrischu
  • 3,047
  • 3
  • 27
  • 44
  • 3
    This can't possibly be possible. How would you write to the database? You'd have to open the assembly for writing. Not answering because I can't provide technical details. –  Apr 26 '09 at 17:10
  • 1
    Even if this was possible, I'd imagine it would send some security suites crazy - large, constant changes to a code file. – dommer Apr 26 '09 at 17:29
  • 3
    If you had a small amount of *read-only* data that you wished to query, this would probably work just fine - read the resource into an in-memory database and query it. – Shog9 Apr 26 '09 at 17:40
  • I might be mistake, but I remmember when dealing with Dotnet 2 there was a way to embed a sql express DB into the exe/dll – Itay Moav -Malimovka Apr 26 '09 at 17:58
  • @Will - We don't want to *write* to the database - we want to use it as a starting point for a `:memory:` hosted database which isn't necessarily retained anywhere. The "solutions" that extract the embedded resource to a file first aren't ideal - really limits the utility of in-memory databases. – Jason Kleban May 08 '13 at 15:27
  • @Shog9 - how can we "read the resource into an in-memory database"? – Jason Kleban May 08 '13 at 15:27
  • @uosɐſ: pretty much the same way you'd read any file into an in-memory SQLite database; poke around a bit, both parts of this are pretty well-documented. For instance: http://stackoverflow.com/questions/433171/how-to-embed-a-text-file-in-a-net-assembly and http://stackoverflow.com/questions/14508502/lightweight-in-memory-database – Shog9 May 08 '13 at 15:59
  • @Shog9 - I can create an in-memory sqlite database and I can read a binary from an embedded resource, but I don't know how to load the memory database with a pre-existing database image without loading it (at some point) from a stand-alone file by path. – Jason Kleban May 08 '13 at 16:47
  • @uosɐſ: I would probably just store the data in some other format (CSV, XML) and load/parse/create the database at run-time. If you're *really* interested in loading a SQLite DB from a stream, I would post that as a separate question. – Shog9 May 08 '13 at 17:29

5 Answers5

16

An assembly isn't for file storage, it's for code storage. While you can store files in an assembly, they are read only.

Samuel
  • 37,778
  • 11
  • 85
  • 87
3

This is not possible as such. What you could do is embed the db in your dll project and dump it to certain location on the file system (may be AppData?) and read and write from there. Having db sit directly inside the executable (or dlls) may not be a good idea in the sense it bloats the size of the application besides being technically infeasible.

Having a single executable to distribute is a matter of taste which I like. In your case but the problems are more. It's not just about embedding the db file alone, what about the dlls associated with it? Steps are 2:

1) Add the necessary dlls (System.Data.SQLite?) associated with your db to your project as Embedded Resource (not necessarily a Resource file) and let the system automatically resolve the assembly conflicts. Catch it here how to do it.

2) Now either add your db file to your Resources of your project (and extract it)

static void DumpDatabase()
{
    var dbFullPath = Utility.GetDbFullPath(); //your path
    if (File.Exists(dbFullPath))
        return; //whatever your logic is

    File.WriteAllBytes(dbFullPath, Properties.Resources.myDb);
}

or even better do not embed the db as such in your project but write the logic to create database in your application. What if tomorrow you need to change the version of SQLite, say from 3 to 4? With the first approach you need to create a database for yourself and re-embed it in the project. But if you are writing the logic to create the db in your application then updating SQLite version is just a matter of changing the ADO.NET dll (the code remains the same). May be like this:

static void DumpDatabase()
{
    var dbFullPath = Utility.GetDbFullPath();
    if (File.Exists(dbFullPath))
        return; //whatever your logic is

    CreateDb(dbFullPath);
}

static void Create(string dbFullPath)
{
    SQLiteConnection.CreateFile(dbFullPath);

    string query = @"

    CREATE TABLE [haha] (.............)
    CREATE TABLE ..............";

    Execute(query);
}

And in the connection string add FailIfMissing=False;

Community
  • 1
  • 1
nawfal
  • 70,104
  • 56
  • 326
  • 368
0

If you're on NTFS, you can use an alternate data stream. On my project we hide the SQLite database inside another file using an alternate stream called :DB.

Anthony Brien
  • 6,106
  • 7
  • 43
  • 56
0

I don't think storing data in DLL is a good idea, but there is a dirty way to do it.

To load data from DLL:

  1. Use System.Reflection.Assembly to load a string from DLL file. (The string is dump of DB)
  2. Create empty SQLite DB in memory.
  3. Use the loaded string as a query to DB to restore its content.

Now you can make any queries in memory.

To save data to DLL:

  1. Dump DB content into a string.
  2. Create temporary file containing SQL-dump wrapped in C# code.
  3. Compile it using "csc" (or "gmcs" in Mono).

It's stupid, but it should work. Hope you will never code that way.

mateusza
  • 5,341
  • 2
  • 24
  • 20
-2

SQLite is packaged and distributed as a single C file with a few (3 I think) header files. This means that you can compile the entire 50000 line program with one compile command and get a .o file. From there, you can link it into your application DLL with the other files you link into that DLL.

Once you build sqlite3.o into your application DLL, the symbols in its SQLite's API become available to your programs in the same way that your other C/C++ DLLs become available to your C#/VB programs.

Check out www.sqlite.org/amalgamation.html for more info.

  • 4
    That was totally not what I was trying to achieve. I wanted to embed the database file in a dll not the dll that allows me to access it. – chrischu May 31 '09 at 15:40