git-ds 0.9.2

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 (51) hide show
  1. data/README.rdoc +795 -0
  2. data/doc/Examples.rdoc +36 -0
  3. data/doc/examples/key_value/kv_get.rb +29 -0
  4. data/doc/examples/key_value/kv_init.rb +20 -0
  5. data/doc/examples/key_value/kv_list.rb +28 -0
  6. data/doc/examples/key_value/kv_remove.rb +29 -0
  7. data/doc/examples/key_value/kv_set.rb +39 -0
  8. data/doc/examples/key_value/model.rb +156 -0
  9. data/doc/examples/key_value/test.rb +50 -0
  10. data/doc/examples/test_suite/model.rb +503 -0
  11. data/doc/examples/test_suite/test.rb +173 -0
  12. data/doc/examples/test_suite/ts_add_bug.rb +65 -0
  13. data/doc/examples/test_suite/ts_add_module.rb +74 -0
  14. data/doc/examples/test_suite/ts_add_module_to_test.rb +78 -0
  15. data/doc/examples/test_suite/ts_add_test.rb +77 -0
  16. data/doc/examples/test_suite/ts_add_test_suite.rb +65 -0
  17. data/doc/examples/test_suite/ts_add_test_to_bug.rb +76 -0
  18. data/doc/examples/test_suite/ts_init.rb +20 -0
  19. data/doc/examples/test_suite/ts_list.rb +118 -0
  20. data/doc/examples/test_suite/ts_perform_test.rb +104 -0
  21. data/doc/examples/test_suite/ts_update_bugs.rb +58 -0
  22. data/doc/examples/user_group/model.rb +265 -0
  23. data/doc/examples/user_group/test.rb +64 -0
  24. data/doc/examples/user_group/ug_add_group.rb +39 -0
  25. data/doc/examples/user_group/ug_add_group_user.rb +36 -0
  26. data/doc/examples/user_group/ug_add_user.rb +39 -0
  27. data/doc/examples/user_group/ug_init.rb +20 -0
  28. data/doc/examples/user_group/ug_list.rb +32 -0
  29. data/lib/git-ds.rb +14 -0
  30. data/lib/git-ds/config.rb +53 -0
  31. data/lib/git-ds/database.rb +289 -0
  32. data/lib/git-ds/exec_cmd.rb +107 -0
  33. data/lib/git-ds/index.rb +205 -0
  34. data/lib/git-ds/model.rb +136 -0
  35. data/lib/git-ds/model/db_item.rb +42 -0
  36. data/lib/git-ds/model/fs_item.rb +51 -0
  37. data/lib/git-ds/model/item.rb +428 -0
  38. data/lib/git-ds/model/item_list.rb +97 -0
  39. data/lib/git-ds/model/item_proxy.rb +128 -0
  40. data/lib/git-ds/model/property.rb +144 -0
  41. data/lib/git-ds/model/root.rb +46 -0
  42. data/lib/git-ds/repo.rb +455 -0
  43. data/lib/git-ds/shared.rb +17 -0
  44. data/lib/git-ds/transaction.rb +77 -0
  45. data/tests/ut_database.rb +304 -0
  46. data/tests/ut_git_grit_equiv.rb +195 -0
  47. data/tests/ut_index.rb +203 -0
  48. data/tests/ut_model.rb +360 -0
  49. data/tests/ut_repo.rb +260 -0
  50. data/tests/ut_user_group_model.rb +316 -0
  51. metadata +142 -0
@@ -0,0 +1,265 @@
1
+ #!/usr/bin/env ruby
2
+ # :title: GitDS Model Example: User/Group
3
+ =begin rdoc
4
+ <i>Copyright 2011 Thoughtgang <http://www.thoughtgang.org></i>
5
+
6
+ This example demonstrates a simple hierarchical data model for managing
7
+ unix-style users and groups.
8
+
9
+ Note: This is not intended as a serious implementation of an auth system. It is
10
+ intended only to illustrate the use of a hierarchical database using a
11
+ familiar data model.
12
+
13
+ ==Usage
14
+
15
+ An example of the usage of this model can be found in the following script:
16
+
17
+ doc/examples/user_group/test.rb
18
+
19
+ This script can be run to generate an example Git-DS repository:
20
+
21
+ bash$ doc/examples/user_group/test.rb
22
+ bash$ cd ug_test.db && qgit &
23
+
24
+ The following command-line utilities are provided for manipulating this
25
+ data model:
26
+
27
+ doc/examples/user_group/ug_add_group.rb
28
+ doc/examples/user_group/ug_add_group_user.rb
29
+ doc/examples/user_group/ug_add_user.rb
30
+ doc/examples/user_group/ug_init.rb
31
+ doc/examples/user_group/ug_list.rb
32
+
33
+
34
+ ===Initialize a TestSuite database
35
+
36
+ # connect the model, creating it if necessary
37
+ model = UserGroupModel.new(GitDS::Database.connect('ug_test.db', true))
38
+
39
+ ===Add a user
40
+
41
+ u = model.add_user(username, id, fullname)
42
+
43
+ ===Add a group
44
+
45
+ g = model.add_group(username, id, owner_name)
46
+
47
+ # add user to group
48
+ u = model.user(username)
49
+ g.add_user(u)
50
+
51
+ =end
52
+
53
+ require 'git-ds/database'
54
+ require 'git-ds/model'
55
+
56
+ =begin rdoc
57
+ The model has the following structure in the repo:
58
+
59
+ user/ : FsModelItemClass
60
+ user/$NAME/ : FsModelItem
61
+ user/$NAME/id : Property
62
+ user/$NAME/full_name : Property
63
+ user/$NAME/created : Property
64
+
65
+ group/ : FsModelItemClass
66
+ group/$NAME/ : FsModelItem
67
+ group/$NAME/id : Property
68
+ group/$NAME/owner : ProxyProperty
69
+ group/$NAME/users : ProxyItemList
70
+ =end
71
+
72
+ class UserGroupModel < GitDS::Model
73
+ def initialize(db)
74
+ super db, 'user/group model'
75
+ end
76
+
77
+ =begin rdoc
78
+ Add a User to the model.
79
+ =end
80
+ def add_user(name, id, fullname='')
81
+ args = {:username => name, :id => id.to_i, :fullname => fullname }
82
+ UserModelItem.new self, UserModelItem.create(self.root, args)
83
+ end
84
+
85
+ =begin rdoc
86
+ Return a list of the usernames of all Users in the model
87
+ =end
88
+ def users
89
+ UserModelItem.list(self.root)
90
+ end
91
+
92
+ =begin rdoc
93
+ Instantiate a User object based on the username.
94
+ =end
95
+ def user(ident)
96
+ UserModelItem.new self, UserModelItem.instance_path(self.root.path, ident)
97
+ end
98
+
99
+ =begin rdoc
100
+ Add a Group to the model.
101
+ =end
102
+ def add_group(name, id, owner_name)
103
+ owner = user(owner_name)
104
+
105
+ args = { :name => name, :id => id.to_i, :owner => owner }
106
+ GroupModelItem.new self, GroupModelItem.create(self.root, args)
107
+ end
108
+
109
+ =begin rdoc
110
+ List the names of all Groups in the model.
111
+ =end
112
+ def groups
113
+ GroupModelItem.list(self.root)
114
+ end
115
+
116
+ =begin rdoc
117
+ Instantiate a Group object by name.
118
+ =end
119
+ def group(ident)
120
+ GroupModelItem.new self, GroupModelItem.instance_path(self.root.path, ident)
121
+ end
122
+ end
123
+
124
+ # ----------------------------------------------------------------------
125
+ =begin rdoc
126
+ A User. Users consist of a UNIX-style username, an ID number, a full name,
127
+ and a timestamp marking when they were created.
128
+ =end
129
+ class UserModelItem < GitDS::FsModelItem
130
+
131
+ name 'user'
132
+
133
+ # properties
134
+ property(:id, 0) { |p| p.to_s.to_i == p }
135
+ property(:full_name, '')
136
+ property(:created)
137
+
138
+ # Use :username entry in Hash as primary key
139
+ def self.ident_key
140
+ :username
141
+ end
142
+
143
+ def self.fill(model, item_path, args)
144
+ super
145
+ properties[:created].set(model, item_path, Time.now.to_s)
146
+ end
147
+
148
+ =begin rdoc
149
+ The name of the user, e.g. 'root'.
150
+ =end
151
+ alias :username :ident
152
+
153
+ =begin rdoc
154
+ The ID number of the user, e.g. 1000.
155
+ =end
156
+ def id
157
+ integer_property(:id)
158
+ end
159
+
160
+ def id=(val)
161
+ set_property(:id, val)
162
+ end
163
+
164
+ =begin rdoc
165
+ The full name of the user, e.g. 'John Q. Public'.
166
+ =end
167
+ def full_name
168
+ property(:full_name)
169
+ end
170
+
171
+ def full_name=(val)
172
+ set_property(:full_name, val)
173
+ end
174
+
175
+ =begin rdoc
176
+ The timestamp when the user was created.
177
+ =end
178
+ def created
179
+ ts_property(:created)
180
+ end
181
+
182
+ end
183
+
184
+ # ----------------------------------------------------------------------
185
+ =begin rdoc
186
+ A group of users. Groups consist of a UNIX-style name, a numeric ID, and
187
+ owner (a valid User), and a list of members (valid Users).
188
+ =end
189
+ class GroupModelItem < GitDS::FsModelItem
190
+
191
+ name 'group'
192
+
193
+ # properties
194
+ property(:id, 0) { |p| p.to_s.to_i == p }
195
+ link_property(:owner, UserModelItem)
196
+
197
+ def initialize(model, path)
198
+ super
199
+ @users = GitDS::ProxyItemList.new(UserModelItem, model, path)
200
+ end
201
+
202
+ # Use :name entry in Hash as primary key
203
+ def self.ident_key()
204
+ :name
205
+ end
206
+
207
+ =begin rdoc
208
+ The name of the group, e.g. 'staff'.
209
+ =end
210
+ alias :name :ident
211
+
212
+ =begin rdoc
213
+ The ID of the group, e.g. 1000.
214
+ =end
215
+ def id
216
+ integer_property(:id)
217
+ end
218
+
219
+ def id=(val)
220
+ set_property(:id, val)
221
+ end
222
+
223
+ =begin rdoc
224
+ The owner of the group: a link to a User object.
225
+ =end
226
+ def owner
227
+ property(:owner)
228
+ end
229
+
230
+ def owner=(u)
231
+ set_property(:owner, u)
232
+ end
233
+
234
+ =begin rdoc
235
+ The names of every User in the group.
236
+ =end
237
+ def users
238
+ ensure_valid
239
+ @users.keys
240
+ end
241
+
242
+ =begin rdoc
243
+ Instantiate a User in the group by name.
244
+ =end
245
+ def user(name)
246
+ ensure_valid
247
+ @users[name]
248
+ end
249
+
250
+ =begin rdoc
251
+ Add a User to the group. The argument must be a User object.
252
+ =end
253
+ def add_user(u)
254
+ ensure_valid
255
+ @users.add(self, u, true)
256
+ end
257
+
258
+ =begin rdoc
259
+ Remove a user from the group, by name.
260
+ =end
261
+ def del_user(name)
262
+ ensure_valid
263
+ @users.delete(name)
264
+ end
265
+ end
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env ruby
2
+ # Test User/Group database example
3
+ # Copyright 2011 Thoughtgang <http://www.thoughtgang.org>
4
+
5
+ BASE=File.dirname(File.expand_path(__FILE__)\
6
+ ).split(File::SEPARATOR)[0..-4].join(File::SEPARATOR)
7
+ $: << BASE + File::SEPARATOR + 'lib'
8
+ $: << BASE + File::SEPARATOR + 'doc' + File::SEPARATOR + 'examples'
9
+
10
+ require 'user_group/model'
11
+
12
+ # ----------------------------------------------------------------------
13
+
14
+ def fill_model(model)
15
+ users = [{ :username => 'root', :id => 1 },
16
+ { :username => 'admin', :id => 1000, :full_name => 'Administrator'},
17
+ { :username => 'humpty', :id => 1001, :full_name => 'H Umpty, Esq.'},
18
+ { :username => 'dumpty', :id => 1002, :full_name => 'Dump Ty'}
19
+ ]
20
+ groups = [ { :name => 'wheel', :id => 1, :owner_name => 'root',
21
+ :members => ['root', 'admin'] },
22
+ { :name => 'staff', :id => 1000, :owner_name => 'admin',
23
+ :members => ['admin', 'humpty', 'dumpty'] },
24
+ { :name => 'twins', :id => 1001, :owner_name => 'humpty',
25
+ :members => ['humpty', 'dumpty'] }
26
+ ]
27
+
28
+ users.each do |udef|
29
+ model.add_user(udef[:username], udef[:id], udef[:full_name])
30
+ end
31
+
32
+ groups.each do |gdef|
33
+ g = model.add_group(gdef[:name], gdef[:id], gdef[:owner_name])
34
+ gdef[:members].each { |name| g.add_user(model.user(name)) }
35
+ end
36
+
37
+ end
38
+
39
+ # ----------------------------------------------------------------------
40
+ def list_model(model)
41
+ puts "Users:"
42
+ model.users.each do |user|
43
+ u = model.user(user)
44
+ puts "\t#{u.id}\t#{u.username}\t#{u.created}\t#{u.full_name}"
45
+ end
46
+
47
+ puts "\nGroups:"
48
+ model.groups.each do |grp|
49
+ puts "\t#{grp}"
50
+ g = model.group(grp)
51
+ puts "\t#{g.id}\t#{g.name}\t#{g.owner.username}\t#{g.users.inspect}"
52
+ end
53
+ end
54
+
55
+ # ----------------------------------------------------------------------
56
+ if __FILE__ == $0
57
+ path = (ARGV.count > 0) ? ARGV.shift : 'ug_test.db'
58
+
59
+ db = GitDS::Database.connect(path, true)
60
+ model = UserGroupModel.new(db) if db
61
+ fill_model(model) if model
62
+ list_model(model) if model
63
+ end
64
+
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+ # Add a group to a User/Group database repo
3
+ # Copyright 2011 Thoughtgang <http://www.thoughtgang.org>
4
+
5
+ # Add examples dir and lib/git-ds to ruby path
6
+ BASE=File.dirname(File.expand_path(__FILE__)\
7
+ ).split(File::SEPARATOR)[0..-4].join(File::SEPARATOR)
8
+ $: << BASE + File::SEPARATOR + 'lib'
9
+ $: << BASE + File::SEPARATOR + 'doc' + File::SEPARATOR + 'examples'
10
+
11
+ require 'user_group/model'
12
+
13
+ if __FILE__ == $0
14
+ if ARGV.count < 3 || ARGV.count > 4
15
+ puts "Usage : #{$0} [FILENAME] NAME ID OWNER"
16
+ puts "Repo dir is assumed to be . if FILENAME is not specified."
17
+ puts "A new GitDS database will be created if FILENAME does not exist."
18
+ exit -1
19
+ end
20
+
21
+ path = ''
22
+ autocreate = false
23
+ if ARGV.count == 4
24
+ path = ARGV.shift
25
+ autocreate = true
26
+ else
27
+ path = GitDS::Database.top_level
28
+ end
29
+ name = ARGV.shift
30
+ id = ARGV.shift
31
+ owner = ARGV.shift
32
+
33
+ model = UserGroupModel.new(GitDS::Database.connect(path, autocreate))
34
+ raise "Could not connect to Model!" if not model
35
+
36
+ model.add_group(name, id, owner)
37
+
38
+ exit 0
39
+ end
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+ # Add a user to a group in a User/Group database repo
3
+ # Copyright 2011 Thoughtgang <http://www.thoughtgang.org>
4
+
5
+ # Add examples dir and lib/git-ds to ruby path
6
+ BASE=File.dirname(File.expand_path(__FILE__)\
7
+ ).split(File::SEPARATOR)[0..-4].join(File::SEPARATOR)
8
+ $: << BASE + File::SEPARATOR + 'lib'
9
+ $: << BASE + File::SEPARATOR + 'doc' + File::SEPARATOR + 'examples'
10
+
11
+ require 'user_group/model'
12
+
13
+ if __FILE__ == $0
14
+ if ARGV.count < 2 || ARGV.count > 3
15
+ puts "Usage : #{$0} [FILENAME] GROUP USER"
16
+ puts "Repo dir is assumed to be . if FILENAME is not specified."
17
+ exit -1
18
+ end
19
+
20
+ path = (ARGV.count == 3) ? ARGV.shift : GitDS::Database.top_level
21
+ group_name = ARGV.shift
22
+ user_name = ARGV.shift
23
+
24
+ model = UserGroupModel.new(GitDS::Database.connect(path, false))
25
+ raise "Could not connect to Model!" if not model
26
+
27
+ g = model.group(group_name)
28
+ raise "Invalid group #{group_name}" if not g
29
+
30
+ u = model.user(user_name)
31
+ raise "Invalid user #{user_name}" if not u
32
+
33
+ g.add_user(u)
34
+
35
+ exit 0
36
+ end
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+ # Add a user to a User/Group database repo
3
+ # Copyright 2011 Thoughtgang <http://www.thoughtgang.org>
4
+
5
+ # Add examples dir and lib/git-ds to ruby path
6
+ BASE=File.dirname(File.expand_path(__FILE__)\
7
+ ).split(File::SEPARATOR)[0..-4].join(File::SEPARATOR)
8
+ $: << BASE + File::SEPARATOR + 'lib'
9
+ $: << BASE + File::SEPARATOR + 'doc' + File::SEPARATOR + 'examples'
10
+
11
+ require 'user_group/model'
12
+
13
+ if __FILE__ == $0
14
+ if ARGV.count < 3 || ARGV.count > 4
15
+ puts "Usage : #{$0} [FILENAME] NAME ID FULLNAME"
16
+ puts "Repo dir is assumed to be . if FILENAME is not specified."
17
+ puts "A new GitDS database will be created if FILENAME does not exist."
18
+ exit -1
19
+ end
20
+
21
+ path = ''
22
+ autocreate = false
23
+ if ARGV.count == 4
24
+ path = ARGV.shift
25
+ autocreate = true
26
+ else
27
+ path = GitDS::Database.top_level
28
+ end
29
+ username = ARGV.shift
30
+ id = ARGV.shift
31
+ fullname = ARGV.shift
32
+
33
+ model = UserGroupModel.new(GitDS::Database.connect(path, autocreate))
34
+ raise "Could not connect to Model!" if not model
35
+
36
+ model.add_user(username, id, fullname)
37
+
38
+ exit 0
39
+ end