Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
ShitDB - YAML-backed document-oriented database in pure ruby
require 'rubygems'
require 'minitest/spec'
require 'minitest/autorun'
require 'yaml'
class DB
def initialize(name)
@name = File.join(File.dirname(__FILE__), name)
end
def collection(name)
Collection.new(self, name)
end
def file
@file ||= File.exist?(@name) ? YAML.load(File.open(@name)) : {}
end
def persist
File.open(@name, 'w') do |f|
f.write YAML.dump(@file)
end
end
end
class Collection
attr_reader :db
def initialize(db, name)
@db = db
@name = name
@db.file[@name] ||= []
@db.file["_#{@name}_last_id"] ||= 0
end
def persist
@db.persist
end
def get(id)
@db.file[@name].detect do |record|
record[:id] == id
end
end
def put(doc)
new_id = @db.file["_#{@name}_last_id"] + 1
@db.file[@name] << doc.update(:id => new_id)
@db.file["_#{@name}_last_id"] = new_id
end
def all
@db.file[@name]
end
def where(attrs)
@db.file[@name].select do |record|
attrs.map do |attr|
record[attr.first] == attr.last
end.all?{|n| n == true}
end
end
end
require 'fileutils'
describe 'acceptance tests' do
before do
FileUtils.rm('my_db') if File.exist?('my_db')
@users = DB.new('my_db').collection('users')
end
describe 'storage' do
it 'saves records in memory' do
@users.put(:name => 'James')
@users.put(:name => 'John', :age => 30)
users = @users.all.map { |record| record[:name] }
assert_equal 2, users.length
assert_includes users, 'James'
assert_includes users, 'John'
end
it 'does not save them to disk' do
@users.put(:name => 'James')
@users.put(:name => 'John', :age => 30)
persisted = DB.new('my_db').collection('users').all
assert_equal 0, persisted.length
end
it 'persists them when told so' do
@users.put(:name => 'James')
@users.put(:name => 'John', :age => 30)
@users.persist
users = DB.new('my_db').collection('users').all.map { |record| record[:name] }
assert_equal 2, users.length
assert_includes users, 'James'
assert_includes users, 'John'
end
end
describe 'querying' do
before do
@users.put(:name => 'James')
@users.put(:name => 'John', :age => 30)
@users.put(:name => 'Charles', :age => 30)
end
it 'performs simple queries with one condition inefficiently' do
result = @users.where(:age => 30).map { |record| record[:name] }
assert_equal 2, result.length
assert_includes result, 'John'
assert_includes result, 'Charles'
end
it 'performs simple queries with multiple conditions inefficiently' do
result = @users.where(:name => 'Charles', :age => 30).map { |record| record[:name]}
assert_equal 1, result.length
assert_equal 'Charles', result.first
end
it 'retrieves records by id' do
james = @users.get(1)
john = @users.get(2)
charles = @users.get(3)
assert_equal 'James', james[:name]
assert_equal 'John', john[:name]
assert_equal 'Charles', charles[:name]
end
end
describe 'consistency' do
it 'assigns autoincremental ids' do
@users.put(:name => 'James')
@users.put(:name => 'John')
ids = @users.all.map { |record| record[:id] }.compact
assert_equal 2, ids.length
refute_equal ids.first, ids.last
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.