georgi-git_store 0.1 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. data/README.md +81 -15
  2. data/git_store.gemspec +1 -1
  3. data/lib/git_store.rb +19 -9
  4. metadata +1 -1
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
- GitStore - using Git as versioned data store in Ruby
2
- ====================================================
1
+ Git Store - using Git as versioned data store in Ruby
2
+ =====================================================
3
3
 
4
4
  GitStore is a small Ruby library, providing an easy interface to the
5
5
  version control system [Git][1]. It aims to use Git as a versioned
@@ -7,16 +7,31 @@ data store much like the well known PStore. Basically GitStore checks
7
7
  out the repository into a in-memory representation, which can be
8
8
  modified and finally committed. In this way your data is stored in a
9
9
  folder structure and can be checked out and examined, but the
10
- application may access the data in a convenient hash-like way.
10
+ application may access the data in a convenient hash-like way. This
11
+ library is based on [Grit][2], the main technology behind [GitHub][3].
12
+
13
+
14
+ ## Installation
15
+
16
+ GitStore can be installed as gem easily, if you have RubyGems 1.2.0:
17
+
18
+ $ gem sources -a http://gems.github.com you only have to do this once)
19
+ $ sudo gem install georgi-git_store
20
+
21
+ If you don't have RubyGems 1.2.0, you may download the package on the
22
+ [github page][4] and build the gem yourself:
23
+
24
+ $ gem build git_store.gemspec
25
+ $ sudo gem install git_store
11
26
 
12
- This library is based on [Grit][2], the main technology behind
13
- [GitHub][3].
14
27
 
15
28
  ## Usage Example
16
29
 
17
30
  First thing you should do, is to initialize a new git repository.
18
31
 
19
- git init
32
+ $ mkdir test
33
+ $ cd test
34
+ $ git init
20
35
 
21
36
  Now you can instantiate a GitStore instance and store some data. The
22
37
  data will be serialized depending on the file extension. So for YAML
@@ -32,19 +47,34 @@ storage you can use the 'yml' extension:
32
47
 
33
48
  store.commit 'Added user and page'
34
49
 
35
- Note that direcories will be created automatically by using the path
36
- syntax. Same for multi arguments hash syntax:
50
+ Note that directories will be created automatically.
51
+
52
+ Another way to access a path is:
37
53
 
38
54
  store[config', 'wiki.yml'] = { 'name' => 'My Personal Wiki' }
39
55
 
40
- In this case the directory config is created automatically and
41
- the file wiki.yml contains be the YAML representation of the given Hash.
56
+ Finally you can access the git store as a Hash of Hashes, but in this
57
+ case you have to create the Tree objects manually:
58
+
59
+ store['users'] = GitStore::Tree.new
60
+ store['users']['matthias.yml'] = User.new('Matthias')
61
+
62
+ ## Where is my data?
63
+
64
+ When you call the `commit` method, your data is written back straight
65
+ into the git repository. No intermediate file representation. So if
66
+ you want to look into your data, you can use some git browser like
67
+ [git-gui][6] or just checkout the files:
68
+
69
+ $ git checkout
70
+
42
71
 
43
72
  ## Iteration
44
73
 
45
- Iterating over the stored datat is one of the common use cases, so
46
- this one is really easy and scales well at the same time, if you user
47
- a clever directory structure:
74
+ Iterating over the data objects is quite easy. Furthermore you can
75
+ iterate over trees and subtrees, so you can partition your data in a
76
+ meaningful way. For example you may separate the config files and the
77
+ pages of a wiki:
48
78
 
49
79
  store['pages/home.yml'] = WikiPage.new('matthias', 'Home', 'This is the home page...')
50
80
  store['pages/about.yml'] = WikiPage.new('matthias', About', 'About this site...')
@@ -54,13 +84,49 @@ a clever directory structure:
54
84
  store.each { |obj| ... } # yields all pages and the config hash
55
85
  store['pages'].each { |page| ... } # yields only the pages
56
86
 
57
- ## References
87
+
88
+ ## Serialization
89
+
90
+ Serialization is dependent on the filename extension. You can add more
91
+ handlers if you like, the interface is like this:
92
+
93
+ class YAMLHandler
94
+ def read(id, name, data)
95
+ YAML.load(data)
96
+ end
97
+
98
+ def write(data)
99
+ data.to_yaml
100
+ end
101
+ end
102
+
103
+ GitStore::Handler['yml'] = YAMLHandler.new
104
+
105
+
106
+ Shinmun uses its own handler for files with `md` extension:
107
+
108
+ class PostHandler
109
+ def read(name, data)
110
+ Post.new(:filename => name, :src => data)
111
+ end
112
+
113
+ def write(post)
114
+ post.dump
115
+ end
116
+ end
117
+
118
+ GitStore::Handler[md'] = PostHandler.new
119
+
120
+
121
+ ## Related Work
58
122
 
59
123
  John Wiegley already has done [something similar for Python][4]. His
60
124
  implementation has its own git interface, GitStore uses the wonderful
61
125
  [Grit][2] library.
62
126
 
63
127
  [1]: http://git.or.cz/
64
- [2]: http://github.com/mojombo/grit/tree/master
128
+ [2]: http://github.com/mojombo/grit
65
129
  [3]: http://github.com/
66
130
  [4]: http://www.newartisans.com/blog_files/git.versioned.data.store.php
131
+ [5]: http://github.com/georgi/git_store
132
+ [6]: http://www.kernel.org/pub/software/scm/git/docs/git-gui.html
data/git_store.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'git_store'
3
- s.version = '0.1'
3
+ s.version = '0.1.1'
4
4
  s.date = '2008-12-17'
5
5
  s.summary = 'a simple data store based on git'
6
6
  s.author = 'Matthias Georgi'
data/lib/git_store.rb CHANGED
@@ -1,10 +1,22 @@
1
1
  require 'grit'
2
- require 'erb'
2
+
3
+ # This fix ensures sorted yaml maps.
4
+ class Hash
5
+ def to_yaml( opts = {} )
6
+ YAML::quick_emit( object_id, opts ) do |out|
7
+ out.map( taguri, to_yaml_style ) do |map|
8
+ sort_by { |k, v| k.to_s }.each do |k, v|
9
+ map.add( k, v )
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
3
15
 
4
16
  class GitStore
5
17
 
6
18
  class DefaultHandler
7
- def read(id, name, data)
19
+ def read(name, data)
8
20
  data
9
21
  end
10
22
 
@@ -14,7 +26,7 @@ class GitStore
14
26
  end
15
27
 
16
28
  class YAMLHandler
17
- def read(id, name, data)
29
+ def read(name, data)
18
30
  YAML.load(data)
19
31
  end
20
32
 
@@ -24,13 +36,13 @@ class GitStore
24
36
  end
25
37
 
26
38
  class RubyHandler
27
- def read(id, name, data)
39
+ def read(name, data)
28
40
  Object.module_eval(data)
29
41
  end
30
42
  end
31
43
 
32
44
  class ERBHandler
33
- def read(id, name, data)
45
+ def read(name, data)
34
46
  ERB.new(data)
35
47
  end
36
48
  end
@@ -52,7 +64,6 @@ class GitStore
52
64
  def initialize(*args)
53
65
  if args.first.is_a?(Grit::Blob)
54
66
  @blob = args.first
55
- @id = @blob.id
56
67
  @name = @blob.name
57
68
  else
58
69
  @name = args[0]
@@ -65,7 +76,7 @@ class GitStore
65
76
  end
66
77
 
67
78
  def load(data)
68
- @data = handler.read(id, name, data)
79
+ @data = handler.read(name, data)
69
80
  end
70
81
 
71
82
  def handler
@@ -93,7 +104,7 @@ class GitStore
93
104
  class Tree
94
105
  include Enumerable
95
106
 
96
- attr_reader :id, :data
107
+ attr_reader :data
97
108
  attr_accessor :name
98
109
 
99
110
  def initialize(name = nil)
@@ -102,7 +113,6 @@ class GitStore
102
113
  end
103
114
 
104
115
  def load(tree)
105
- @id = tree.id
106
116
  @name = tree.name
107
117
  @data = tree.contents.inject({}) do |hash, file|
108
118
  if file.is_a?(Grit::Tree)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: georgi-git_store
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.1"
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthias Georgi