Project

json_store

0.0
No commit activity in last 3 years
No release in over 3 years
A simple in memory key/value database using json that writes to file
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.0
~> 2.0.1
~> 3.0.0.rc1

Runtime

 Project Readme

PLEASE NOTE - This project is not being actively maintained at the moment - I am taking a break - not sure when I will return.

json_store

Build Status Gem Version json_store downloads

Very simple key/value in memory database using json

Install

gem install json_store

Usage

require 'json_store'

db = JsonStore.new('names.db')
db.pull
db.set(:name,'Kingsley')
p db.get(:name # Kingsley)
db.merge
db.push

# if removing items use write instead of merge and push
db.pull
db.remove(:name)
db.write # write replaces file with in memory data
  • Peristing more complex things like custom objects
class Person

  def initialize(first,last)
    @first = first
    @last = last
  end

  def first
    @first
  end

  def last
    @last
  end

end

db = JsonStore.new('people')
db.pull
db.set(:person,Person.new('Kingsley','Hendrickse'))
db.push
p db.get(:person).first # Kingsley

There are only a handful of commands:

  • pull
  • push
  • merge
  • set
  • get
  • get_as_json
  • search
  • all
  • all_as_json
  • clear
  • set_json_opts
  • get_json_opts

The basic concept is that you create new db with the JsonStore.new and if the db is already a valid json file you can do pull to populate the in memory map. If no file exists then one will be created.

  • When you want to add to the db - you use set(key,value)
  • When you want to push your data to file there are a couple of options - push or merge then push

Merge and Push

calling push will replace the db on file with the current content of the local map. Calling merge will merge the file db with the current in memory map after which you can call push to store the data. If you are happy to replace the db file with the content of your local map just use push. If you think there might be changes to the db file that you want before overwriting the file - then call merge to get them and then ovewrite with push.

Merge has 2 possibilities - :into_local and :into_remote - the default is :into_remote e.g.

 db.merge(:into_local)
  • :into_local will read the file content and then merge it into the local map - overwriting local changes with ones from file where the key is the same
  • :into_remote will read the local map into the data from file - thus keeping any local changes and overwriting file items where the key is the same

Get and Search

There are 2 ways to find data:

  • Get
  • Search

Get just finds a value by key e.g.

   db.set(:name,'Kingsley')
   db.get(:name) # Kingsley

Search uses the json select gem (https://github.com/fd/json_select) and (http://jsonselect.org/#overview) to provide advanced searching capability. If you persist custom ruby objects however this searching method will not work as it will only work with the standard json types. But then you can just use regular ruby to find things e.g. take, select, reject, find. sort_by etc

Read the documentation in the links above for a better idea how to use it - here is a simple example:

  db.set(:names,[{id:1,name:'Kingsley'},{id:2,name:'Kostas'}])
  db.search('.names .name') # ['Kingsley','Kostas']
  db.search('.names .name',:match) # "Kingsley"
  db.search('.names object:last-child .name',:match) # "Kostas"

Search takes 2 parameters: the selector and a match kind - which is set to :matches by default. The options are:

  • :matches - returns an array of data - is the default
  • :match - returns only the first match
  • :test - returns true or false if there is a match

Persisting Objects

When persisting objects - such as the Person class mentioned earlier - the default method of serialization used by Oj is :object. Which means it will expand the object into json format with an entry containg an O to denote it's an object. Oj has several other notations for Array etc.

But if you want to have nicer json so you can use it elsewhere as a feed for example - you might prefer to use the :compat mode which looks for a to_json method on the object and uses that to serialize it. So you can add your own to_json method. Please note that when retrieving data again it will be as hash/array data not the ruby custom object initially created - because the :compat mode will force serialization to be the standard supported json - e.g. hash/arrays. If you want to persist objects and retrieve them then stick with the default serialization. Here is an example of using compat:

class Car

  attr_reader :doors,:wheels

  def initialize(doors,wheels)
   @doors = doors
   @wheels = wheels
  end

  def to_json
    puts %Q{ { "doors":#{@doors},"wheels",#{@wheels}} }
  end

end

db = JsonStore.new('cars')
db.set_json_opts(mode: :compat,indent: 2)
db.set(:cars,[Car.new(4,4),Car.new(2,3])
p db.all_as_json

Contributing to json_store

  • Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
  • Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
  • Fork the project.
  • Start a feature/bugfix branch.
  • Commit and push until you are happy with your contribution.
  • Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
  • Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.

Copyright

Copyright (c) 2014 Kingsley Hendrickse. See LICENSE.txt for further details.