JSONdb Ruby gem

Tiny local database JSON lib

View the Project on GitHub fernandezvara/jsondb

JSONdb

This lib helps to create a little database organized in different JSON files inside a folder. It allows to interact inside a process with the data you need.

Why use this underpowered lib instead of a real database?

Well, this lib comes from one motivation: Currently we have really big repositories with Vagrant/Chef configuration that are used for too many people at the same time with many applications/environments/versions (around ~500 combinations). Everyone can provision any machine on development environments so it's hard to predict where, where, what or why something is changed.

To avoid human errors updating the big 'versions.rb' file (~500 lines) we made a first version of this lib using sqlite3 and it worked really nice.

But just three days later problems araise again. Someone forgot to pull the repo before make a change of a version using the versions cli helper. I'm still figuring how to fix a sqlite database file after an unresolved merge.

Breaking something in a text file it's easy to fix, so let's make again the versions database but don't edit the files directly.

I hope this can be useful for someone else.

To start using it:

$ gem install jsondb

Or just add it to your Gemfile

source 'https://rubygems.org'
gem 'jsondb'

How to use

require 'jsondb'

# remember that folder must exists or it will raise an error 
# (it's supposed that you want to use old data if exists)
# true if you want to allow writes

db = Db.new('/tmp/dbtest', true)     

Tables

# create a table
db.table_add("table_a")       # Allowed characters

# remove a table
db.table_remove("table_a")  

# create/use a table  
db.table("table_a")

Fields

# by default all tables have an id, created_at and updated_at 
# fields for every record in the table

db.table("table_a").fields.keys 
=>  ["id", "created_at", "updated_at"]

field = db.table("table_a").field("field_a")
field.nullable = true   # defaults to true
field.type = "String"   # defaults to "String". Allowed values: 
    # "Integer", "Float", "String", "Time", "Bool"
field.default = ""      # defaults to nil

db.table("table_a").fields.keys 
=>  ["id", "created_at", "updated_at", "field_a"]

Records

record = db.table("table_a").new_record
record.field_a = "Sample data"

db.table("table_a").insert(record) # inserting a record

record.id 
=>  1

db.table("table_a").insert(record) 
    # fails, that record already exists!

record.field_a = "Another data"
db.table("table_a").update(record)

# Another record

record2 = db.table("table_a")
record2.field_a = 333 
    # Fails on validation 333 is a Numeric Type not String

db.table("table_a").insert(record)

db.table("table_a").records.count
=> 2

Persistence

db.persist 
# It saves database structure and all the tables 
# that have changed in the session

Queries

query = db.table("table_a").select 
  # returns an object ResultSet

result = query.result 
  # this is a select * from table_a;

result = query.equal("field_a", "Sample Data").result
  # select * from table_a where field_a="Sample Data";

result.count
==> 1

# you can use:
#  equal(field, value)
#  min(field, value)
#  max(field, value)
#  like(field, value)

# Queries are chainable
result = query.min("id", 1).max("id", 3).result

# do something with the data....
result.each do |id, record|
  puts record.field_a
end

Feature development and Tests

For testing it uses rspec and guard to help doing in more dynamically. On the Gemfile are already defined all the required gems.


  bundle install
  guard

  -or-

  rspec spec/db_spec.rb

Authors and Contributors

Antonio Fdez. @fernandezvara