gitmodel 0.0.6 → 0.0.7
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.
- data/.gitignore +2 -1
- data/Gemfile.lock +22 -20
- data/README.md +42 -35
- data/gitmodel.gemspec +1 -1
- data/lib/gitmodel/index.rb +1 -3
- data/lib/gitmodel/persistable.rb +35 -0
- data/spec/gitmodel/persistable_spec.rb +28 -0
- metadata +21 -22
- data/.rvmrc +0 -3
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
gitmodel (0.0.
|
4
|
+
gitmodel (0.0.7)
|
5
5
|
activemodel (>= 3.0.1)
|
6
6
|
activesupport (>= 3.0.1)
|
7
7
|
grit (>= 2.3.0)
|
@@ -12,32 +12,34 @@ PATH
|
|
12
12
|
GEM
|
13
13
|
remote: http://rubygems.org/
|
14
14
|
specs:
|
15
|
-
ZenTest (4.
|
16
|
-
activemodel (3.
|
17
|
-
activesupport (= 3.
|
18
|
-
builder (~>
|
19
|
-
i18n (~> 0.
|
20
|
-
activesupport (3.
|
15
|
+
ZenTest (4.6.2)
|
16
|
+
activemodel (3.1.3)
|
17
|
+
activesupport (= 3.1.3)
|
18
|
+
builder (~> 3.0.0)
|
19
|
+
i18n (~> 0.6)
|
20
|
+
activesupport (3.1.3)
|
21
|
+
multi_json (~> 1.0)
|
21
22
|
autotest (4.4.6)
|
22
23
|
ZenTest (>= 4.4.1)
|
23
|
-
builder (
|
24
|
-
diff-lcs (1.1.
|
24
|
+
builder (3.0.0)
|
25
|
+
diff-lcs (1.1.3)
|
25
26
|
grit (2.4.1)
|
26
27
|
diff-lcs (~> 1.1)
|
27
28
|
mime-types (~> 1.15)
|
28
|
-
i18n (0.
|
29
|
-
lockfile (1.
|
29
|
+
i18n (0.6.0)
|
30
|
+
lockfile (2.1.0)
|
30
31
|
memcache-client (1.8.5)
|
31
|
-
mime-types (1.
|
32
|
-
|
33
|
-
|
34
|
-
rspec-
|
35
|
-
rspec-
|
36
|
-
|
37
|
-
rspec-
|
32
|
+
mime-types (1.17.2)
|
33
|
+
multi_json (1.0.4)
|
34
|
+
rspec (2.7.0)
|
35
|
+
rspec-core (~> 2.7.0)
|
36
|
+
rspec-expectations (~> 2.7.0)
|
37
|
+
rspec-mocks (~> 2.7.0)
|
38
|
+
rspec-core (2.7.1)
|
39
|
+
rspec-expectations (2.7.0)
|
38
40
|
diff-lcs (~> 1.1.2)
|
39
|
-
rspec-mocks (2.
|
40
|
-
yajl-ruby (
|
41
|
+
rspec-mocks (2.7.0)
|
42
|
+
yajl-ruby (1.1.0)
|
41
43
|
|
42
44
|
PLATFORMS
|
43
45
|
ruby
|
data/README.md
CHANGED
@@ -56,7 +56,9 @@ See the "To do" section below for details, but the main thing that needs
|
|
56
56
|
finishing is support for querying. Right now you can find an instance by it's
|
57
57
|
id, but there is incomplete support (90% complete) for querying, e.g.:
|
58
58
|
|
59
|
-
|
59
|
+
```ruby
|
60
|
+
Post.find(:category => 'ruby', :date => lambda{|d| d > 1.month.ago} :order_by => :date, :order => :asc, :limit => 5)
|
61
|
+
```
|
60
62
|
|
61
63
|
This includes support for indexing all attributes so that queries don't need to
|
62
64
|
load every object.
|
@@ -73,44 +75,46 @@ It's available as a [RubyGem](https://rubygems.org/gems/gitmodel):
|
|
73
75
|
Usage
|
74
76
|
-----
|
75
77
|
|
76
|
-
|
77
|
-
|
78
|
+
```ruby
|
79
|
+
GitModel.db_root = '/tmp/gitmodel-data'
|
80
|
+
GitModel.create_db!
|
78
81
|
|
79
|
-
|
80
|
-
|
82
|
+
class Post
|
83
|
+
include GitModel::Persistable
|
81
84
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
85
|
+
attribute :title
|
86
|
+
attribute :body
|
87
|
+
attribute :categories, :default => []
|
88
|
+
attribute :allow_comments, :default => true
|
86
89
|
|
87
|
-
|
88
|
-
|
90
|
+
blob :image
|
91
|
+
end
|
89
92
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
+
p1 = Post.new(:id => 'lessons-learned', :title => 'Lessons learned', :body => '...')
|
94
|
+
p1.image = some_binary_data
|
95
|
+
p1.save!
|
93
96
|
|
94
|
-
|
97
|
+
p = Post.find('lessons-learned')
|
95
98
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
99
|
+
p2 = Post.new(:id => 'hotdog-eating-contest', :title => 'I won!')
|
100
|
+
p2.body = 'This weekend I won a hotdog eating contest!'
|
101
|
+
p2.image = some_binary_data
|
102
|
+
p2.blobs['hotdogs.jpg'] = some_binary_data
|
103
|
+
p2.blobs['the-aftermath.jpg'] = some_binary_data
|
104
|
+
p2.save!
|
102
105
|
|
103
|
-
|
106
|
+
p3 = Post.create!(:id => 'running-with-scissors', :title => 'Running with scissors', :body => '...')
|
104
107
|
|
105
|
-
|
108
|
+
p4 = Post.find('running-with-scissors')
|
106
109
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
110
|
+
class Comment
|
111
|
+
include GitModel::Persistable
|
112
|
+
attribute :text
|
113
|
+
end
|
111
114
|
|
112
|
-
|
113
|
-
|
115
|
+
c1 = Comment.create!(:id => '2010-01-03-328', :text => '...')
|
116
|
+
c2 = Comment.create!(:id => '2010-05-29-742', :text => '...')
|
117
|
+
```
|
114
118
|
|
115
119
|
|
116
120
|
An example of a project that uses GitModel is [Balisong](https://github.com/pauldowman/balisong), a blogging app for coders (but it doesn't save objects to the data store. It's read-only so far, assuming that posts will be edited with a text editor).
|
@@ -156,8 +160,10 @@ Performance
|
|
156
160
|
|
157
161
|
GitModel supports memcached for query results. This is off by default, but can be configured like this:
|
158
162
|
|
159
|
-
|
160
|
-
|
163
|
+
```ruby
|
164
|
+
GitModel.memcache_servers(['server_1', 'server_2', ...])
|
165
|
+
GitModel.memcache_namespace('optional_namespace')
|
166
|
+
```
|
161
167
|
|
162
168
|
The namespace is optional, and usually not necessary because GitModel will prepend the last segment of GitModel.db_root anyway.
|
163
169
|
|
@@ -165,9 +171,9 @@ A Git SHA is also prepended to every key, so that outdated versions will not be
|
|
165
171
|
|
166
172
|
There is still a lot of work to be done to make it faster. First, some analysis is required, but some guesses about things that would help are:
|
167
173
|
|
168
|
-
|
169
|
-
|
170
|
-
|
174
|
+
* Use [Rugged](https://github.com/libgit2/rugged) instead of Grit
|
175
|
+
* Remove the transaction lock (see transaction.rb line 19)
|
176
|
+
* Ability to iterate over result set without eager loading of all instances
|
171
177
|
|
172
178
|
|
173
179
|
Contributing
|
@@ -175,13 +181,14 @@ Contributing
|
|
175
181
|
|
176
182
|
Do you have an improvement to make? Please submit a pull request on GitHub or a
|
177
183
|
patch, including a test written with RSpec. To run all tests simply run
|
178
|
-
`
|
184
|
+
`autotest`.
|
179
185
|
|
180
186
|
The main author is [Paul Dowman](http://pauldowman.com/about) ([@pauldowman](http://twitter.com/pauldowman)).
|
181
187
|
|
182
188
|
Thanks to everyone who has contributed so far:
|
183
189
|
|
184
190
|
* [Alex Bartlow](https://github.com/alexbartlow)
|
191
|
+
* [Daniel Russo](https://github.com/drusso)
|
185
192
|
|
186
193
|
|
187
194
|
To do
|
data/gitmodel.gemspec
CHANGED
data/lib/gitmodel/index.rb
CHANGED
data/lib/gitmodel/persistable.rb
CHANGED
@@ -54,6 +54,23 @@ module GitModel
|
|
54
54
|
@id = string
|
55
55
|
end
|
56
56
|
|
57
|
+
# Get the location of the record relative to the repository's root.
|
58
|
+
#
|
59
|
+
# It is determined by appending the name of the directory containing
|
60
|
+
# the record with the record's +id+.
|
61
|
+
def path
|
62
|
+
@path ||= File.join(self.class.db_subdir, self.id)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Get the branch that the record was last loaded from or was last
|
66
|
+
# saved on.
|
67
|
+
#
|
68
|
+
# The branch specified in the +GitModel+ config is used by default.
|
69
|
+
# Typically, the branch is 'master'.
|
70
|
+
def branch
|
71
|
+
@branch ||= GitModel.default_branch
|
72
|
+
end
|
73
|
+
|
57
74
|
def attributes
|
58
75
|
@attributes
|
59
76
|
end
|
@@ -115,6 +132,12 @@ module GitModel
|
|
115
132
|
end
|
116
133
|
end
|
117
134
|
|
135
|
+
if result
|
136
|
+
@path = dir
|
137
|
+
@branch = transaction.branch
|
138
|
+
@new_record = false
|
139
|
+
end
|
140
|
+
|
118
141
|
result
|
119
142
|
end
|
120
143
|
end
|
@@ -124,6 +147,15 @@ module GitModel
|
|
124
147
|
save(options) || raise(GitModel::RecordNotSaved)
|
125
148
|
end
|
126
149
|
|
150
|
+
# Reloads a record and returns the model instance.
|
151
|
+
#
|
152
|
+
# The record is reloaded from the branch that the record
|
153
|
+
# was last loaded from or last saved to.
|
154
|
+
def reload
|
155
|
+
load(path, branch)
|
156
|
+
self
|
157
|
+
end
|
158
|
+
|
127
159
|
def delete(options = {})
|
128
160
|
freeze
|
129
161
|
self.class.delete(id, options)
|
@@ -142,6 +174,9 @@ module GitModel
|
|
142
174
|
# todo find a better way to ensure path is safe
|
143
175
|
dir.gsub!(/\.\./, '')
|
144
176
|
|
177
|
+
@path = dir
|
178
|
+
@branch = branch
|
179
|
+
|
145
180
|
raise GitModel::RecordNotFound if GitModel.current_tree(branch).nil?
|
146
181
|
|
147
182
|
self.id = File.basename(dir)
|
@@ -118,6 +118,34 @@ describe GitModel::Persistable do
|
|
118
118
|
end
|
119
119
|
end
|
120
120
|
|
121
|
+
describe'#reload' do
|
122
|
+
|
123
|
+
it 'reloads persisted attributes' do
|
124
|
+
o = TestEntity.new(:id => 'foo')
|
125
|
+
o.attributes['A'] = 'A'
|
126
|
+
o.save
|
127
|
+
o.attributes['B'] = 'B'
|
128
|
+
|
129
|
+
o.attributes['A'].should == 'A'
|
130
|
+
o.attributes['B'].should == 'B'
|
131
|
+
o.reload
|
132
|
+
o.attributes['A'].should == 'A'
|
133
|
+
o.attributes['B'].should == nil
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'returns the reloaded instance' do
|
137
|
+
o = TestEntity.create(:id => 'foo')
|
138
|
+
p = o.reload
|
139
|
+
o.should == p
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'raises an exception if the document is not found' do
|
143
|
+
lambda { TestEntity.new.reload }.should raise_error
|
144
|
+
lambda { TestEntity.new(:id => "foo").reload }.should raise_error
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
121
149
|
describe '.create' do
|
122
150
|
|
123
151
|
it 'creates a new instance with the given parameters and calls #save on it' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitmodel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-12-23 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|
16
|
-
requirement: &
|
16
|
+
requirement: &70229033519260 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 3.0.1
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70229033519260
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: activesupport
|
27
|
-
requirement: &
|
27
|
+
requirement: &70229033512340 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 3.0.1
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70229033512340
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: grit
|
38
|
-
requirement: &
|
38
|
+
requirement: &70229033511660 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 2.3.0
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70229033511660
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: lockfile
|
49
|
-
requirement: &
|
49
|
+
requirement: &70229033510920 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 1.4.3
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70229033510920
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: memcache-client
|
60
|
-
requirement: &
|
60
|
+
requirement: &70229033510380 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 1.8.5
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70229033510380
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: yajl-ruby
|
71
|
-
requirement: &
|
71
|
+
requirement: &70229033509920 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: 0.8.2
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70229033509920
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: ZenTest
|
82
|
-
requirement: &
|
82
|
+
requirement: &70229033509460 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: 4.4.0
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70229033509460
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: autotest
|
93
|
-
requirement: &
|
93
|
+
requirement: &70229033508980 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ! '>='
|
@@ -98,10 +98,10 @@ dependencies:
|
|
98
98
|
version: 4.4.1
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *70229033508980
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
103
|
name: rspec
|
104
|
-
requirement: &
|
104
|
+
requirement: &70229033508520 !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
107
|
- - ! '>='
|
@@ -109,7 +109,7 @@ dependencies:
|
|
109
109
|
version: 2.0.1
|
110
110
|
type: :development
|
111
111
|
prerelease: false
|
112
|
-
version_requirements: *
|
112
|
+
version_requirements: *70229033508520
|
113
113
|
description: GitModel persists Ruby objects using Git as a data storage engine. It's
|
114
114
|
an ActiveModel implementation so it works stand-alone or in Rails 3 as a drop-in
|
115
115
|
replacement for ActiveRecord or DataMapper. Because the database is a Git repository
|
@@ -123,7 +123,6 @@ files:
|
|
123
123
|
- .document
|
124
124
|
- .gitignore
|
125
125
|
- .rspec
|
126
|
-
- .rvmrc
|
127
126
|
- Gemfile
|
128
127
|
- Gemfile.lock
|
129
128
|
- LICENSE
|
@@ -161,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
161
160
|
version: '0'
|
162
161
|
requirements: []
|
163
162
|
rubyforge_project:
|
164
|
-
rubygems_version: 1.8.
|
163
|
+
rubygems_version: 1.8.11
|
165
164
|
signing_key:
|
166
165
|
specification_version: 3
|
167
166
|
summary: An ActiveModel-compliant persistence framework for Ruby that uses Git for
|
data/.rvmrc
DELETED