Giter VIP home page Giter VIP logo

dustbin's Introduction

Dustbin JS

Build Status

A JSON-backed object database for your web browser. It's a light wrapper around local/session storage, designed to behave much like a standard NoSQL database. (In fact, it's design is heavily influenced by Riak, my personal favoriate NoSQL.)

Overview

Dustbin has the concepts of 'bins', which are loosely analogous to tables in SQL, or collections/buckets in NoSQL. Basically, they are collections of objects able to be referenced by a name. (In fact, Dustbin simply uses an anonymous object for each bin).

Inside each bin, objects are stored by key. Keys are always strings, but they can be any key you can set on a javascript object. The objects that are stored must be able to be turned into a JSON string. That is the only restriction. (Really, it's the cost of doing business with localStorage; it doesn't support storage of objects, only strings and integers.)

Metadata support

Dustbin does modify the stored objects slightly. In each object, it adds a key called $metadata, which stores useful information about the object, such as the key, and the bucket it was saved in, or the creation time. This object is for both internal use, as well as providing possibly useful data to the user. You may store whatever additional data you would like in the object; just be aware that whenever the object is stored, Dustbin will always override key, bucket, and updated.

Currently, here is an example $metadata object:

{
    key: "someKey",
    bin: "someBin",
    created: "Tue Apr 15 2013 23:05:42 GMT-0500 (CDT)",
    updated: "Tue Apr 16 2013 09:01:38 GMT-0500 (CDT)"
}

It should be noted that created and updated are always strings. You can turn them into Date objects trivially:

    var createdDate = new Date(obj.$metadata.created);

Usage

Using Dustbin is incredibly easy. When you include dustbin, it creates a new object on window, called dustbin. Here's an example of basic usage:

var obj = {'foo': "bar"};

// Store the object.
dustbin.store("testBin", "testObj", obj);

// Store an object if it already contains metadata.
dustbin.store(obj);

// Retrieve it by key.
obj = dustbin.get("testBin", "testObj");

// Alternative syntax.
obj = dustbin.get("testBin")["testObj"];

That's all there is to it!

RequireJS support

Recently, I've added support for RequireJS. While it's optional (and will remain so), the support seems to work very well. You can simply use it like any other RequireJS module:

require(['dustbin'], function(dustbin)
{
    var key = dustbin.store("testBin", obj);
});

Though the support has been tested (and is part of the unit tests), I still consider the RequireJS support experimental. If you encounter any issues, please file a ticket. (Make sure to include a test case!)

Auto-generated Keys

You're not required to have a key to store your object under. Dustbin will automatically generate a key for you if you don't pass one in:

var obj = {'foo': "bar"};

// Store the object.
var key = dustbin.store("testBin", obj);

// Key will be something like: "LTMwMzk5OTQ2MA=="
console.log("Key:", key);

// Retrieve it by key.
obj = dustbin.get("testBin", key);

Retrieve entire bin object

You can also retrieve the entire bin object:

bin = dustbin.get("testBin");

This allows for the alternative (and in my opinion, cleaner) syntax:

obj = dustbin.get("testBin")["testObj"];

Remove an object

You can remove an object by key:

dustbin.remove("testBin", "testObj");

Remove all objects in a bin

You can even remove all objects from a bin:

dustbin.removeAllKeys("testBin");

Basic Query support

Currently, only basic query support has been added. You will need to construct an object containing key and value where you want back a list of object that have key equal to value. Here's an example:

var alex = {animal:"cat", name: "alex", age: 4};
var izzy = {animal:"cat", name: "izzy", age: 4};
var baal = {animal:"snake", name: "baal", age: 2};

dustbin.store("pets", alex);
dustbin.store("pets", izzy);
dustbin.store("pets", baal);

// `cats` will be equal to `[alex, izzy]`
var cats = dustbin.query("pets", {animal: "cat"});

// `pets` will be equal to `[alex, izzy, baal]`
var pets = dustbin.query("pets", {});

Right now the only thing supported is pure equality, not equivalence. Also, this is basically two nested forEach calls, so performance isn't as good as it could be. I'll be looking at improving this in the future, but for now it should meet most needs.

Session store support

All operations can also be done on the session store. By default, the dustbin object's functions are simply wrappers for dustbin.local. As such, you can also access the session store by using: dustbin.session. Here's some examples:

var obj = {'foo': "bar"};

// Store the object.
dustbin.session.store("testBin", "testObj", obj);

// Retrieve it by key.
obj = dustbin.session.get("testBin", "testObj");

// Alternative syntax.
obj = dustbin.session.get("testBin")["testObj"];

As you can see, it supports all the same operations as the local storage functions. There is absolutely no difference, except the inherent difference of session storage (all objects only last for the duration of the browser session.)

Status

Currently, all unit tests pass, and the basic functionality is there. You can get, remove and store objects by key. There is also basic query support, which I estimate will work for 70% of most use cases. As near as I can tell, this code is simple enough it can be used in a production site.

That being said, I would very much like to add support for map/reduce and a django-like query api. I will work on that as I have time. If you would like to implement these features, I am more than willing to accept pull requests.

Contribution

As mentioned, I'm more than willing to accept pull requests. I will require you to follow my code format. I also reserve the rights to reject any features that rely heavily on experimental features, or lock users into one way system for using Dustbin. (There's a readon why the RequireJS support is optional.)

Reporting issues

I'm more than happy to have issues reported! All that I ask is a clear description of the problem, along with a test case. I don't have the time or inclination to wade through your application to try and discover the causes for a bug. So, whenever possible, please try and give me a small test case (Or, preferably, a pull-request with new unit tests that show the failure!)

That all being said, don't wait to file a bug until you have a use case. I'd rather know there's a potential issue asap; you can feel free to file an issue, and attach the test case to it later. Just make it clear you're working on it. If you're having trouble isolating it, I'm more than willing to lend a hand, provided I have the time. Feel free to ask.

dustbin's People

Contributors

lordnull avatar morgul avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

dustbin's Issues

[RFC] Add Link Support

I'm proposing we add support for links between objects in Dustbin. This could be very useful to managing data relationships.

Link Format:

A link would be an object of this structure:

{
    tag: [{bucket: "some_bucket", key: "some_key"}];
}

We would add links to the $metadata (proposed in #4 ), which would simply be the above object with multiple tags.

Working with Links

The first thing we would need is an api for adding/removing links:

// Add a link to obj1 from obj1 to obj2 with the tag 'tag'.
dustbin.link(obj1, 'tag', obj2);

// Add a link to obj1 from obj1 to the object at bucket/key with the tag 'tag'.
dustbin.link(obj1, 'tag', 'bucket', 'key');

// Adds links to obj1 from ob1 to obj2, obj3 and obj4 with the tag 'tag'.
dustbin.addLinks(obj1, 'tag', obj2, obj3, obj4);

// Adds links to obj1 from ob1 to the objects at 'bucket/ket1' and 'bucket/key2' with the tag 'tag'.
dustbin.addLinks(obj1, 'tag', ["bucket", "key1"], ["bucket", "key2"]);

// Remove a link from obj1 with the tag 'tag', that points to obj2.
dustbin.unlink(obj1, 'tag', obj2);

// Remove a link from obj1 with the tag 'tag', that points to the object 'bucket/key'.
dustbin.unlink(obj1, 'tag', 'bucket', 'key');

// Sets the links on object obj1 to the `link` object passed in.
dustbin.setLinks(obj1, {tag: [{bucket: "bucket", key: "someKey"}]});

These should cover most of the use cases. We still need the ability to work with the links:

// Get all links associated with the given tag. Returns a list of resolved objects.
dustbin.getLinks(obj1, 'tag');

// Link walk object 1
dustbin.walk(obj1, ["bucket", "tag"], [undefined, "someTag", true]);

// Link walk object 1, verbose syntax
dustbin.walk(obj1, {bucket: "bucket", tag: "tag"}, {tag: "someTag", keep: true});

This is pretty much the exact same link walking as Riak, with the exception that instead of using "_", I'm using undefined to mean "any". I believe that simply not specifying one of the options is more straightforward than an arbitrary (if commonly used) string convention.


In the end, the API is less important than answering the question, "Will this be useful?". While I can see use cases, I'm not certain that they're worth adding this support in.

If we're not sure if we want this, but thing it might be useful in some places, I'd like to write it as an extension to Dustbin; i.e. if you include dustbin.js and dustbin-links.js the DustBin object would have it's prototype extended to support links. This way, only the people who want them will need to include the additional code, and any overhead it might induce.

Add RequireJS support

This module should (optionally) be able to be used with RequireJS.

It is incredibly important that RequireJS be optional. It should always be usable as a normal javascript include.

Implement Query API

Implement a query api, inspired by django's query api.

Basically, how I would like this to work is like this:

dustbin.query({someKey: "valueToMatch", someOtherKey: "someOtherValueToMatch"});

We can support the field api from django like this:

dustbin.query({someKey__lt: 5, someOtherKey__contains: "partial string"});

Alternatively, we could do this using a jugglingdb like api:

dustbin.query({lessThan: {someKey: 5}, contains: {someOtherKey: "partial string"}});

I'm not sure which I like better.

query and get do not return key of stored item

It can be useful to know what key an item was stored in to make later retrieval easier, as well as allow for reference by other objects. Perhaps stored as a '_key' property, or using an interal '_id' property.

It may be useful to store objects wrapped to allow meta data to avoid needing to dictate any form of structure upon the stored data.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.