Tiny local database JSON lib
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.
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'
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)
# 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")
# 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"]
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
db.persist
# It saves database structure and all the tables
# that have changed in the session
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
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
Antonio Fdez. @fernandezvara