hash_db 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Guardfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +117 -0
- data/Rakefile +1 -0
- data/hash_db.gemspec +25 -0
- data/lib/hash_db/model/association.rb +51 -0
- data/lib/hash_db/model/core.rb +59 -0
- data/lib/hash_db/model/query.rb +29 -0
- data/lib/hash_db/version.rb +3 -0
- data/lib/hash_db.rb +9 -0
- data/spec/hash_db/model/association_spec.rb +51 -0
- data/spec/hash_db/model/core_spec.rb +80 -0
- data/spec/hash_db/model/query_spec.rb +46 -0
- data/spec/hash_db_spec.rb +7 -0
- data/spec/spec_helper.rb +5 -0
- metadata +123 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Utkarsh Kukreti
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
# HashDB
|
2
|
+
|
3
|
+
HashDB is a minimal, in-memory, ActiveRecord like database library,
|
4
|
+
backed by a Ruby Hash.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Gem releases are not done frequently as of now. I recommend installing through
|
9
|
+
the git repository.
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'hash_db', git: "https://github.com/utkarshkukreti/hash_db.git"
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ git clone https://github.com/utkarshkukreti/hash_db.git
|
22
|
+
$ cd hash_db
|
23
|
+
$ bundle install
|
24
|
+
$ rake install
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
First, require HashDB.
|
29
|
+
|
30
|
+
require 'hash_db'
|
31
|
+
|
32
|
+
To make your class a HashDB model, just include `HashDB::Model` module in
|
33
|
+
your class.
|
34
|
+
|
35
|
+
class Post
|
36
|
+
include HashDB::Model
|
37
|
+
end
|
38
|
+
|
39
|
+
Defining attributes is as easy as calling `keys`, with the key names you want.
|
40
|
+
|
41
|
+
keys :title, :content
|
42
|
+
|
43
|
+
HashDB will automatically create getters and setters for these keys, so you can
|
44
|
+
now assign `title` and `content` to objects of the Post class.
|
45
|
+
|
46
|
+
post = Post.new
|
47
|
+
post.title = "Introducing HashDB"
|
48
|
+
post.content = "..."
|
49
|
+
|
50
|
+
Just as with ActiveRecord, you can also pass a Hash with key/value pairs to .new
|
51
|
+
|
52
|
+
# Same as above
|
53
|
+
post = Post.new title: "Introducing HashDB", content: "..."
|
54
|
+
|
55
|
+
To be able to query the model, objects must be saved, using `.save`.
|
56
|
+
|
57
|
+
post.save
|
58
|
+
|
59
|
+
This saves the object into Class.all Hash, with auto generated `id` key as the
|
60
|
+
key, and object as the value.
|
61
|
+
|
62
|
+
Post.all == { 1 => post } #= true
|
63
|
+
|
64
|
+
Like ActiveRecord, `.new` and `.save` can be combined into just a `.create` call
|
65
|
+
on the class.
|
66
|
+
|
67
|
+
Post.create title: "Second Post"
|
68
|
+
Post.all.count == 2 #= true
|
69
|
+
|
70
|
+
## Querying
|
71
|
+
|
72
|
+
HashDB currently has just 2 query methods, `.where`, which can filter objects
|
73
|
+
using key(s) = value(s), and also using custom method call, like `:<` and `:>`.
|
74
|
+
|
75
|
+
Let's [HN](http://news.ycombinator.com) as an example. :)
|
76
|
+
|
77
|
+
class Item
|
78
|
+
include HashDB::Model
|
79
|
+
keys :url, :title, :points, :comment_count
|
80
|
+
end
|
81
|
+
|
82
|
+
Item.create url: "http://blog.heroku.com/archives/2011/7/12/matz_joins_heroku/",
|
83
|
+
title: "Matz (creator of Ruby) joins Heroku",
|
84
|
+
points: 569,
|
85
|
+
comment_count: 79
|
86
|
+
Item.create url: "http://www.rubymotion.com/",
|
87
|
+
title: "RubyMotion - Ruby for iOS",
|
88
|
+
points: 466,
|
89
|
+
comment_count: 248
|
90
|
+
Item.create url: "http://repl.it/",
|
91
|
+
title: "Try Python, Ruby, Lua, Scheme, QBasic, Forth...",
|
92
|
+
points: 379,
|
93
|
+
comment_count: 80
|
94
|
+
|
95
|
+
You can query by key = value
|
96
|
+
|
97
|
+
Item.where(points: 569).count #= 1
|
98
|
+
|
99
|
+
by key = value pairs
|
100
|
+
|
101
|
+
Item.where(points: 569, comment_count: 79).count #= 1
|
102
|
+
|
103
|
+
by custom method call
|
104
|
+
|
105
|
+
Item.where(:points, :>, 400).count #= 2
|
106
|
+
|
107
|
+
and by custom method call pairs
|
108
|
+
|
109
|
+
Item.where([:points, :>, 400], [:title, :=~, /ios/i]).count #= 1
|
110
|
+
|
111
|
+
## Associations
|
112
|
+
|
113
|
+
TODO: Add Documentation
|
114
|
+
|
115
|
+
## License
|
116
|
+
|
117
|
+
MIT License. (c) 2013 Utkarsh Kukreti.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/hash_db.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'hash_db/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "hash_db"
|
8
|
+
gem.version = HashDB::VERSION
|
9
|
+
gem.authors = ["Utkarsh Kukreti"]
|
10
|
+
gem.email = ["utkarshkukreti@gmail.com"]
|
11
|
+
gem.description = "A minimal, in-memory, ActiveRecord like database, " +
|
12
|
+
"backed by a Ruby Hash."
|
13
|
+
gem.summary = gem.description
|
14
|
+
gem.homepage = ""
|
15
|
+
gem.license = "MIT"
|
16
|
+
|
17
|
+
gem.files = `git ls-files`.split($/)
|
18
|
+
gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
20
|
+
gem.require_paths = ["lib"]
|
21
|
+
|
22
|
+
%w{rake rspec guard-rspec}.each do |name|
|
23
|
+
gem.add_development_dependency name
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module HashDB
|
2
|
+
module Model
|
3
|
+
module ClassMethods
|
4
|
+
def has_many(name, args = {})
|
5
|
+
klass = args[:class]
|
6
|
+
foreign_key = args[:foreign_key]
|
7
|
+
|
8
|
+
klass.keys foreign_key
|
9
|
+
|
10
|
+
define_method "#{name}" do
|
11
|
+
base_id = id
|
12
|
+
@attributes[name] ||= begin
|
13
|
+
[].tap do |array|
|
14
|
+
array.define_singleton_method :<< do |object|
|
15
|
+
object.send("#{foreign_key}=", base_id)
|
16
|
+
super object
|
17
|
+
end
|
18
|
+
|
19
|
+
array.define_singleton_method :create do |*args|
|
20
|
+
klass.create(*args).tap do |object|
|
21
|
+
array << object
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def belongs_to(name, args = {})
|
30
|
+
klass = args[:class]
|
31
|
+
key = args[:key]
|
32
|
+
|
33
|
+
define_method "#{name}" do
|
34
|
+
@attributes[name]
|
35
|
+
end
|
36
|
+
|
37
|
+
define_method "#{name}=" do |object|
|
38
|
+
@attributes[name] = object
|
39
|
+
end
|
40
|
+
|
41
|
+
define_method "#{key}" do
|
42
|
+
@attributes[name] && @attributes[name].id
|
43
|
+
end
|
44
|
+
|
45
|
+
define_method "#{key}=" do |id|
|
46
|
+
@attributes[name] = klass.find_by(id: id)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module HashDB
|
2
|
+
module Model
|
3
|
+
attr_accessor :attributes
|
4
|
+
|
5
|
+
def self.included(klass)
|
6
|
+
klass.extend ClassMethods
|
7
|
+
klass.all = {}
|
8
|
+
klass.keys :id
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(args = {})
|
12
|
+
@attributes = {}
|
13
|
+
args.each do |key, value|
|
14
|
+
if respond_to?("#{key}=")
|
15
|
+
send("#{key}=", value)
|
16
|
+
else
|
17
|
+
raise InvalidKeyError.new "Invalid key #{key}."
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def save
|
23
|
+
if id.nil?
|
24
|
+
self.id = if self.class.all.any?
|
25
|
+
self.class.all.keys.last + 1
|
26
|
+
else
|
27
|
+
1
|
28
|
+
end
|
29
|
+
end
|
30
|
+
self.class.all[id] = self
|
31
|
+
end
|
32
|
+
|
33
|
+
def destroy
|
34
|
+
self.class.all.delete id
|
35
|
+
end
|
36
|
+
|
37
|
+
module ClassMethods
|
38
|
+
attr_accessor :all
|
39
|
+
|
40
|
+
def keys(*keys)
|
41
|
+
keys.each do |key|
|
42
|
+
define_method "#{key}" do
|
43
|
+
@attributes[key]
|
44
|
+
end
|
45
|
+
|
46
|
+
define_method "#{key}=" do |value|
|
47
|
+
@attributes[key] = value
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def create(args = {})
|
53
|
+
new(args).tap do |object|
|
54
|
+
object.save
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module HashDB
|
2
|
+
module Model
|
3
|
+
module ClassMethods
|
4
|
+
def where(*args)
|
5
|
+
# Doesn't really take all cases into account.
|
6
|
+
# Good enough for now. :)
|
7
|
+
if args.size == 1 && Hash === args.first
|
8
|
+
args = args.first.map do |key, value|
|
9
|
+
[key, :==, value]
|
10
|
+
end
|
11
|
+
elsif !(Array === args.first)
|
12
|
+
args = [args]
|
13
|
+
end
|
14
|
+
|
15
|
+
@all.values.select do |object|
|
16
|
+
args.all? do |key, method, value|
|
17
|
+
# TODO: Should access through the getter?
|
18
|
+
object.attributes[key].send(method, value)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def find_by(*args)
|
24
|
+
# Not efficient, and I know it.
|
25
|
+
where(*args).first
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/hash_db.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe HashDB::Model do
|
4
|
+
context ".has_many" do
|
5
|
+
it "should allow assigning and retrieving objects" do
|
6
|
+
post = Class.new do
|
7
|
+
include HashDB::Model
|
8
|
+
end
|
9
|
+
|
10
|
+
user = Class.new do
|
11
|
+
include HashDB::Model
|
12
|
+
has_many :posts, foreign_key: :user_id, class: post
|
13
|
+
end
|
14
|
+
|
15
|
+
u1 = user.create
|
16
|
+
u2 = user.create
|
17
|
+
p1 = post.create
|
18
|
+
p2 = post.create
|
19
|
+
|
20
|
+
u1.posts << p1
|
21
|
+
p1.user_id.should eq u1.id
|
22
|
+
u2.posts << p1
|
23
|
+
p1.user_id.should eq u2.id
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context ".belongs_to" do
|
28
|
+
it "should allow assigning and retrieving objects" do
|
29
|
+
user = Class.new do
|
30
|
+
include HashDB::Model
|
31
|
+
end
|
32
|
+
|
33
|
+
post = Class.new do
|
34
|
+
include HashDB::Model
|
35
|
+
belongs_to :user, key: :user_id, class: user
|
36
|
+
end
|
37
|
+
|
38
|
+
u1 = user.create
|
39
|
+
u2 = user.create
|
40
|
+
p1 = post.create
|
41
|
+
p2 = post.create
|
42
|
+
|
43
|
+
p1.user = u1
|
44
|
+
p1.user_id.should eq u1.id
|
45
|
+
p1.user = u2
|
46
|
+
p1.user_id.should eq u2.id
|
47
|
+
p1.user_id = u1.id
|
48
|
+
p1.user.should eq u1
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe HashDB::Model do
|
4
|
+
let(:model) { Class.new { include HashDB::Model } }
|
5
|
+
|
6
|
+
context "include" do
|
7
|
+
it "should be includable" do
|
8
|
+
model.ancestors.should include HashDB::Model
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context ".keys" do
|
13
|
+
it "should allow assigning and retrieving attributes" do
|
14
|
+
model.keys :integer, :string, :float, :object
|
15
|
+
|
16
|
+
m1 = model.new
|
17
|
+
|
18
|
+
m1.integer = 2
|
19
|
+
m1.string = "Hello"
|
20
|
+
m1.float = 4.2
|
21
|
+
m1.object = m1
|
22
|
+
|
23
|
+
m1.integer.should eq 2
|
24
|
+
m1.string.should eq "Hello"
|
25
|
+
m1.float.should eq 4.2
|
26
|
+
m1.object.should eq m1
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context ".new" do
|
31
|
+
it "should assign passed args into keys" do
|
32
|
+
model.keys :integer, :string
|
33
|
+
m1 = model.new integer: 1, string: "test"
|
34
|
+
m1.integer.should eq 1
|
35
|
+
m1.string.should eq "test"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should raise ArgumentError if an invalid key is passed" do
|
39
|
+
expect { model.new invalid: 1 }.to raise_exception HashDB::InvalidKeyError
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context ".create" do
|
44
|
+
it "should instantiate and save object" do
|
45
|
+
model.keys :integer
|
46
|
+
m1 = model.create
|
47
|
+
m2 = model.create integer: 10
|
48
|
+
model.all.should eq({1 => m1, 2 => m2})
|
49
|
+
m2.integer.should eq 10
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "#save" do
|
54
|
+
it "should assign id to models after they are saved" do
|
55
|
+
m1 = model.new.save
|
56
|
+
m1.id.should eq 1
|
57
|
+
m2 = model.new
|
58
|
+
m3 = model.new.save
|
59
|
+
m3.id.should eq 2
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should save model into Class.all" do
|
63
|
+
m1 = model.new
|
64
|
+
m2 = model.new.save
|
65
|
+
m3 = model.new.save
|
66
|
+
model.all.should eq({ 1 => m2, 2 => m3 })
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "#destroy" do
|
71
|
+
it "should remove object from model.all" do
|
72
|
+
m1 = model.create
|
73
|
+
m2 = model.create
|
74
|
+
m1.destroy
|
75
|
+
model.all.should eq({ 2 => m2 })
|
76
|
+
m2.destroy
|
77
|
+
model.all.should be_empty
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe HashDB::Model do
|
4
|
+
let :model do
|
5
|
+
Class.new do
|
6
|
+
include HashDB::Model
|
7
|
+
keys :integer, :string
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context ".where" do
|
12
|
+
context "with hash" do
|
13
|
+
it "should filter by key(s) = value(s)" do
|
14
|
+
m1 = model.create integer: 4, string: "a"
|
15
|
+
m2 = model.create integer: 4, string: "b"
|
16
|
+
m3 = model.create string: "c"
|
17
|
+
m4 = model.create string: "b"
|
18
|
+
|
19
|
+
model.where(integer: 4).should eq [m1, m2]
|
20
|
+
model.where(string: "b").should eq [m2, m4]
|
21
|
+
model.where(string: "d").should eq []
|
22
|
+
model.where(integer: 4, string: "b").should eq [m2]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "with array" do
|
27
|
+
it "should filter by [key, method, value](s)" do
|
28
|
+
m1 = model.create integer: 1
|
29
|
+
m2 = model.create integer: 2
|
30
|
+
m3 = model.create integer: 3
|
31
|
+
m4 = model.create integer: 4
|
32
|
+
model.where(:integer, :<, 2).should eq [m1]
|
33
|
+
model.where(:integer, :>, 2).should eq [m3, m4]
|
34
|
+
model.where([:integer, :>, 0], [:integer, :<, 3]).should eq [m1, m2]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context ".find_by" do
|
40
|
+
it "should delegate to .where.first" do
|
41
|
+
model.should_receive(:where).with(:integer, :<, 10).and_return([])
|
42
|
+
model.find_by(:integer, :<, 10).should eq nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hash_db
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Utkarsh Kukreti
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-02 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: guard-rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: A minimal, in-memory, ActiveRecord like database, backed by a Ruby Hash.
|
63
|
+
email:
|
64
|
+
- utkarshkukreti@gmail.com
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- .gitignore
|
70
|
+
- .rspec
|
71
|
+
- Gemfile
|
72
|
+
- Guardfile
|
73
|
+
- LICENSE.txt
|
74
|
+
- README.md
|
75
|
+
- Rakefile
|
76
|
+
- hash_db.gemspec
|
77
|
+
- lib/hash_db.rb
|
78
|
+
- lib/hash_db/model/association.rb
|
79
|
+
- lib/hash_db/model/core.rb
|
80
|
+
- lib/hash_db/model/query.rb
|
81
|
+
- lib/hash_db/version.rb
|
82
|
+
- spec/hash_db/model/association_spec.rb
|
83
|
+
- spec/hash_db/model/core_spec.rb
|
84
|
+
- spec/hash_db/model/query_spec.rb
|
85
|
+
- spec/hash_db_spec.rb
|
86
|
+
- spec/spec_helper.rb
|
87
|
+
homepage: ''
|
88
|
+
licenses:
|
89
|
+
- MIT
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options: []
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ! '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
hash: 4016006914544296771
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
segments:
|
110
|
+
- 0
|
111
|
+
hash: 4016006914544296771
|
112
|
+
requirements: []
|
113
|
+
rubyforge_project:
|
114
|
+
rubygems_version: 1.8.24
|
115
|
+
signing_key:
|
116
|
+
specification_version: 3
|
117
|
+
summary: A minimal, in-memory, ActiveRecord like database, backed by a Ruby Hash.
|
118
|
+
test_files:
|
119
|
+
- spec/hash_db/model/association_spec.rb
|
120
|
+
- spec/hash_db/model/core_spec.rb
|
121
|
+
- spec/hash_db/model/query_spec.rb
|
122
|
+
- spec/hash_db_spec.rb
|
123
|
+
- spec/spec_helper.rb
|