Skip to content

Latest commit

 

History

History
162 lines (112 loc) · 5.04 KB

README.md

File metadata and controls

162 lines (112 loc) · 5.04 KB

DotStash

An extremely simple data store intended for rapid prototyping or extremely light-weight projects where simple data persistence is required but a full DB is overkill.

Send me a tweet Follow me

Why bother? The main itches driving this project were wanting:

  • serverless
  • minimal config required. No creating databases, setting user permissions etc
  • minimal external dependencies
  • no attributes / etc imposed on persisted classes
  • data stored in a simple readable format (i.e. JSON) for ease of both
    • rapid prototyping (edit documents in any text editor); and
    • easily read and verify results in automated tests

Minimum Requirements / Dependencies

  • .Net Framework 3.5 Client Profile
  • NServiceKit.Text

Works on Mono for Linux, untested in other non-Windows environments.

It does use some C#6 features so assumes Visual Studio 2015 or equivalent if intending to edit or build from source.

Limitations

Set your expectations low. It is NOT a full fledged database by any stretch of the imagination. It does not currently, nor is it ever likely to, support things like:

  • Querying
  • Relationships
  • Schemaless collections
  • Indexing
  • Composite keys
  • Logging
  • Analytics

...or any of the various other things you probably take for granted each time you interact with a database.

It is not going to happen in the immediately foreseeable future but it may, depending on my needs, one day support:

  • Transactions
  • Configure primary key by func (i.e. complex/composite keys possible)
  • Auto-number / auto-generated IDs (only for int and GUID types)

One more time just in case you missed it earlier - THIS IS NOT A DATABASE!

Examples

Basic usage

Data format
private class Widget
{
    public int Id { get; set; }
    public string Value { get; set; }
}
Storage and retrieval
var db = new LocalDataStore("WidgetSoftInventory");            

// Storage
db.Save(new Widget {Id = 1337, Value = value});

// Retrieval by ID
var result = db.Get<Widget>(1337);

// Retrieval of all items of given type
var results = db.GetAll<Widget>();

Configuration

Primary key settings
var db = new LocalDataStore("AlbatrossAirlines");

// Change default key property from "Id"
db.Config.DefaultKeyProperty = "AAID";

// Change key property only for specific types
db.Configure<VipCustomer>(keyName: "FrequentFlyerNumber");
Disk persistence settings
// Changing data storage root path from the default (in %AppData%\SimpleDataStore)
db.Config.DataStoreRootPath = Environment.GetCommandLineArgs()[0];
db.Config.DataStoreRootPath = @"D:\CI\Albatross\TestData";

// Changing the file extension for each document (default is ".json")
db.Config.RecordFileExtension = ".txt";

// Use full class name for storing documents. This is to avoid conflicts in similarly
// named classes (e.g. "Foo.Contact" and "Widget.Domain.Contact")
db.Config.UseFullNameAsFolder = true;

// Override the class name entirely for the data storage folder
db.Configure<CustomerViewmodel>(folderName: "customers");
Info which might be useful for integration tests
// Get folder where all instances of a specific class will be persisted
var widgetJsonFolder = db.DataPath<Widget>();

// Get location on disk where a specific instance will be persisted
var widget = new Widget{ Id = 1337, Value = "o hai" };
var widgetJsonPath = db.GetFileName(widget);
Clean up after yourself
// Deleting all of a single type (roughly equivalent to "DELETE FROM Widget;")
db.DeleteFolder<Widget>();

// Deleting the entire data store
db.DeleteDataStore();

// Automatically delete data store when instance is disposed
db.Config.CleanupOnExit = true;
using(var db = new LocalDataStore("SandwichFactory")
{
    db.Save(new Order {Id = 1, Comments = "Slice off crusts please"});
    db.Save(new Order {Id = 2, Comments = "Don't forget the salt and pepper"});

    // TODO: Get by ID 2 and assert that result is as expected

} // Data store will be deleted here

Miscellaneous notes

Default configuration is intended to be as quick and painless as possible to get up and running. This means making some small assumptions:

  • Classes use an Id property as a unique identifier / primary key
  • Data store folders (i.e. 'tables' in RDBMS land) are named after the class they contain

There is no distinction between Create or Update in a traditional CRUD sense because - that's right - this is not a database. Anything you save overwrites anything else in that collection which has the same key.

License

NServiceKit.Text: view license

Other than for that, the rest of this code is licensed under do-whatever-you-want license. Use at your own risk, no liabilities accepted blah blah blah.