Created
July 7, 2019 09:15
-
-
Save seki/9a7cda3e189e888ce4bfb07eeb36211e to your computer and use it in GitHub Desktop.
a simple kvs using git (rugged)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rugged' | |
require 'cgi' | |
class Grip | |
def initialize(dir) | |
@dir = dir | |
@git = Rugged::Repository.new(@dir) rescue git_init | |
@author = {email: '[email protected]', name: 'seki'} | |
@message = 'via grip' | |
end | |
attr_reader :git | |
def git_init | |
Rugged::Repository.init_at(@dir) | |
end | |
def to_path(key) | |
CGI.escape(key) | |
end | |
def to_key(path) | |
CGI.unescape(path) | |
end | |
def store(key, value, mtime=Time.now) | |
oid = @git.write(value, :blob) | |
index = @git.index | |
tree = @git.head.target.tree rescue [] | |
index.read_tree(tree) rescue nil | |
path = to_path(key) | |
index.add(path: path, oid: oid, mode: 0100644) | |
author = {time: mtime}.update(@author) | |
parents = @git.empty? ? [] : [@git.head.target].compact | |
Rugged::Commit.create( | |
@git, | |
tree: index.write_tree(@git), | |
author: author, | |
committer: author, | |
parents: parents, | |
update_ref: 'HEAD', | |
message: "via grip" | |
) | |
oid | |
end | |
def []=(key, value) | |
store(key, value, Time.now) | |
end | |
def [](key) | |
fetch(key)&.force_encoding("UTF-8") | |
end | |
def fetch(key) | |
path = to_path(key) | |
sha = @git.head.target.tree.get_entry(path)&.dig(:oid) | |
return nil unless sha | |
@git.lookup(sha).content | |
end | |
def keys | |
each_key.to_a | |
end | |
def each_key | |
return to_enum(:each_key) unless block_given? | |
@git.head.target.tree.each {|e| yield(to_key(e[:name]))} | |
end | |
def each | |
return to_enum(:each) unless block_given? | |
@git.head.target.tree.each {|e| | |
yield(to_key(e[:name]), | |
@git.lookup(e[:oid]).content.force_encoding("UTF-8")) | |
} | |
end | |
def history | |
w = Rugged::Walker.new(@git) | |
w.push(@git.head.target.oid) | |
w.each do |commit| | |
yield(commit) | |
end | |
w.reset | |
nil | |
end | |
end | |
if __FILE__ == $0 | |
g = Grip.new('tmp/grip') | |
name = "NS1-5000" | |
s = Time.now | |
30000.times do |x| | |
if x % 100 == 0 | |
p [x, Time.now - s] | |
s = Time.now | |
end | |
name = name.succ | |
g[name] = <<EOS | |
= #{name} | |
empty item | |
== status | |
* 種類: task / story / bug | |
* イテレーション: | |
* サイン: ((<rwiki>)) | |
* 状態: open | |
* 見積: 0 / 0 | |
* テスト分類: | |
* テストレート: | |
== description | |
== test | |
* Q: test.. | |
* A: answer.. | |
== history | |
* #{Time.now.strftime("%Y-%m-%d")} rwiki: open | |
EOS | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment