tonto 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,50 @@
1
+ tonto
2
+ =====
3
+
4
+ > stupid key-value document store ( that uses git as DB )
5
+
6
+ description
7
+ -----------
8
+
9
+ **tonto** ( which can be translated from Italian to *git* ) is a _simple_, _high-level_ and a bit _stupid_ document-oriented store that allows you to use git repos as schema-less NoSQL databases.
10
+
11
+ synopsis
12
+ --------
13
+
14
+ require 'tonto'
15
+ db = Tonto::Repo.new("/my/git/db")
16
+
17
+ db.put {
18
+ :id => 26,
19
+ :name => "My first post",
20
+ :content => "This is COOOL",
21
+ :date => "Time.now"
22
+ }
23
+
24
+ db.get(26)["name"]
25
+
26
+ > My First post
27
+
28
+ db.put({:id => 26, :name => "I'm tonto"})
29
+ > true
30
+
31
+ db.get(26)["name"]
32
+
33
+ > "I'm tonto"
34
+
35
+ db.remove(26)
36
+
37
+ > true
38
+
39
+ db.get(26)
40
+
41
+ > false
42
+
43
+ misc
44
+ ----
45
+
46
+ * status: "alpha status"
47
+
48
+ * license: AGPLv3
49
+
50
+ inspired by [technoweenie](http://git-nosql-rar.heroku.com/), [nimbus](https://github.com/cloudhead/nimbus) and [gitmodel](https://github.com/pauldowman/gitmodel/)
@@ -0,0 +1,12 @@
1
+ require 'grit'
2
+ require 'json'
3
+
4
+ dir = File.dirname(File.expand_path(__FILE__))
5
+ $LOAD_PATH.unshift(File.join('tonto'))
6
+ $LOAD_PATH.unshift(dir)
7
+
8
+ require 'tonto/repo'
9
+
10
+ module Tonto
11
+ VERSION = "0.0.0"
12
+ end
@@ -0,0 +1,65 @@
1
+ module Tonto
2
+
3
+ class Repo
4
+
5
+ attr_accessor :path, :db, :ids
6
+
7
+ def initialize(path)
8
+
9
+ @path = path
10
+
11
+ if File.exist?(@path) == false
12
+ Grit::Repo.init(@path)
13
+ end
14
+
15
+ @db = Grit::Repo.new(path)
16
+ @index = Grit::Index.new(@db)
17
+
18
+ # Loads the list of known documents
19
+ # !!! Find a better way to do this !!!
20
+ @db.commits.any? ? ids = tri.contents.map {|c| c.name.to_i} : ids = []
21
+ @ids = ids
22
+ end
23
+
24
+ def tri
25
+ @db.commits.first.nil? ? [] : (@db.commits.first).tree
26
+ end
27
+
28
+ def get(id)
29
+ object = tri / File.join(id.to_s, "attributes.json")
30
+ return JSON.parse(object.data, :max_nesting => false)
31
+ end
32
+
33
+ def put(doc)
34
+ if @ids.include?(doc[:id])
35
+ old = get(doc[:id].to_s)
36
+ doc.merge!(old)
37
+ add(doc)
38
+ else
39
+ add(doc)
40
+ end
41
+ end
42
+
43
+ def add(doc)
44
+ @index.add(File.join(doc[:id].to_s, "attributes.json"), JSON.pretty_generate(doc))
45
+ if doc.has_key?(:blobs) && doc[:blobs].is_a?(Hash)
46
+ doc[:blobs].each do |k,v|
47
+ @index.add(File.join(doc[:id].to_s, k), v)
48
+ end
49
+ end
50
+ @index.commit("document #{doc[:id]}")
51
+ end
52
+
53
+ # HORRIBLE!!!11!1!
54
+ def remove(id)
55
+ #@index.delete(File.join(id.to_s, "attributes.json"))
56
+ raise "NotImplemented"
57
+ end
58
+
59
+ def exist? id
60
+ @ids.include?(id)
61
+ end
62
+
63
+ alias :exists? :exist?
64
+ end
65
+ end
@@ -0,0 +1,26 @@
1
+ require 'test/unit'
2
+
3
+ dir = File.dirname(File.expand_path(__FILE__))
4
+ $LOAD_PATH.unshift(File.join(dir, '..', 'lib'))
5
+ $LOAD_PATH.unshift(dir)
6
+
7
+ require 'tonto'
8
+
9
+ # Make sure we're in the test dir, the tests expect that to be the current
10
+ # directory.
11
+ TEST_DIR = File.join(File.dirname(__FILE__), *%w[.])
12
+
13
+ def context(*args, &block)
14
+ return super unless (name = args.first) && block
15
+ require 'test/unit'
16
+ klass = Class.new(defined?(ActiveSupport::TestCase) ? ActiveSupport::TestCase : Test::Unit::TestCase) do
17
+ def self.test(name, &block)
18
+ define_method("test_#{name.gsub(/\W/,'_')}", &block) if block
19
+ end
20
+ def self.xtest(*args) end
21
+ def self.setup(&block) define_method(:setup, &block) end
22
+ def self.teardown(&block) define_method(:teardown, &block) end
23
+ end
24
+ (class << klass; self end).send(:define_method, :name) { name.gsub(/\W/,'_') }
25
+ klass.class_eval &block
26
+ end
Binary file
@@ -0,0 +1,54 @@
1
+ require 'digest/md5'
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "helper"))
3
+
4
+ context "db" do
5
+
6
+ setup do
7
+ @db = Tonto::Repo.new("example")
8
+ end
9
+
10
+
11
+ test "repo path" do
12
+ assert_equal "example", @db.path
13
+ end
14
+
15
+ test "git repo" do
16
+ assert_equal Grit::Repo, @db.db.class
17
+ end
18
+
19
+ test "put a new document with id" do
20
+ assert @db.put({:id => 12, :name => "tonto", :says => "i'm not stupid :("})
21
+ end
22
+
23
+ test "get a document by id" do
24
+ assert @db.get(12)
25
+ assert_equal "tonto", @db.get(12)["name"]
26
+ end
27
+
28
+ test "ask if a key exists" do
29
+ assert @db.exist?(12)
30
+ assert @db.exists?(12)
31
+ end
32
+
33
+ #NEEDS REVIEW
34
+ test "update a document" do
35
+ assert @db.put({:id => 12, :nickname => "git"})
36
+ assert_equal "git", @db.get(12)["nickname"]
37
+ end
38
+
39
+ test "remove a document" do
40
+ assert @db.remove(12)
41
+ assert_equal nil, @db.get(12)
42
+ end
43
+
44
+ test "add a blob" do
45
+ assert @db.put :id => 3, :name => "logo", :blobs => {'octocat' => "octocat.png"}
46
+ digest = Digest::MD5.hexdigest(File.read("octocat.png"))
47
+ assert_equal digest, Digest::MD5.hexdigest(@db.get(3)["blobs"]["octocat"])
48
+ end
49
+
50
+ #teardown do
51
+ # FileUtils.rm_rf(@db.path)
52
+ #end
53
+
54
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tonto
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 0
9
+ version: 0.0.0
10
+ platform: ruby
11
+ authors:
12
+ - Ermenegildo Fiorito
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-01-13 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: grit
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: json
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :runtime
45
+ version_requirements: *id002
46
+ description: "**tonto** ( which can be translated from Italian to *git* ) is a _simple_, _high-level_ and a bit _stupid_ document-oriented store that allows you to use git repos as schema-less NoSQL databases."
47
+ email: fiorito.g@gmail.com
48
+ executables: []
49
+
50
+ extensions: []
51
+
52
+ extra_rdoc_files: []
53
+
54
+ files:
55
+ - README.md
56
+ - lib/tonto/repo.rb
57
+ - lib/tonto.rb
58
+ - test/helper.rb
59
+ - test/test_tonto.rb
60
+ - test/octocat.png
61
+ has_rdoc: true
62
+ homepage: http://github.com/fyskij/tonto#readme
63
+ licenses: []
64
+
65
+ post_install_message:
66
+ rdoc_options: []
67
+
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ segments:
76
+ - 0
77
+ version: "0"
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ segments:
84
+ - 0
85
+ version: "0"
86
+ requirements: []
87
+
88
+ rubyforge_project:
89
+ rubygems_version: 1.3.7
90
+ signing_key:
91
+ specification_version: 3
92
+ summary: stupid key-value document store ( that uses git as DB ).
93
+ test_files:
94
+ - test/test_tonto.rb