Class: TmsuModel
Constant Summary
collapse
- Config =
{ root_path: "." }
- Validations =
Hash.new { |h,k| h[k] = [] }
- Callbacks =
{}
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
#build_tag_arg, #files, #merge_tag, #require_persisted, #tag, #tag_selector, #tags, #untag, #untag_selector
Constructor Details
#initialize(attrs = {}, &blk) ⇒ TmsuModel
Returns a new instance of TmsuModel.
114
115
116
117
118
119
120
121
122
123
124
|
# File 'lib/tmsu_file_db.rb', line 114
def initialize(attrs={}, &blk)
attrs = attrs.with_indifferent_access
@path = blk ? blk.call : build_path
@attributes = attrs
@persisted = File.exists? @path
@errors = []
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(sym, *arguments, &blk) ⇒ Object
Forwards method missing to getter, if possible To respect indifferent access of attributes, uses has_key? instead of keys.include?
150
151
152
153
154
155
156
157
|
# File 'lib/tmsu_file_db.rb', line 150
def method_missing(sym, *arguments, &blk)
super unless defined?(attributes) && attributes.is_a?(Hash)
if attributes.has_key? sym
attributes[sym]
else
super
end
end
|
Instance Attribute Details
#attributes ⇒ Object
Returns the value of attribute attributes.
112
113
114
|
# File 'lib/tmsu_file_db.rb', line 112
def attributes
@attributes
end
|
#errors ⇒ Object
Returns the value of attribute errors.
112
113
114
|
# File 'lib/tmsu_file_db.rb', line 112
def errors
@errors
end
|
#path ⇒ Object
Returns the value of attribute path.
112
113
114
|
# File 'lib/tmsu_file_db.rb', line 112
def path
@path
end
|
Class Method Details
.add_callback(name, &blk) ⇒ Object
46
47
48
|
# File 'lib/tmsu_file_db.rb', line 46
def self.add_callback name, &blk
Callbacks[name] = blk
end
|
.all ⇒ Object
88
89
90
|
# File 'lib/tmsu_file_db.rb', line 88
def self.all
Dir.glob(query_glob).map &method(:from_file)
end
|
31
32
33
34
35
|
# File 'lib/tmsu_file_db.rb', line 31
def self.configure(root_path:)
Config[:root_path] = root_path || "./db".tap do |path|
`mkdir -p #{path}`
end
end
|
.create(attrs) ⇒ Object
61
62
63
|
# File 'lib/tmsu_file_db.rb', line 61
def self.create(attrs)
new(attrs).tap(&:save)
end
|
.destroy_all(opts = {}) ⇒ Object
108
109
110
|
# File 'lib/tmsu_file_db.rb', line 108
def self.destroy_all opts={}
Dir.glob(query_glob).tap { |list| list.each { |path| `rm #{path}` } }
end
|
.escape_hash_whitespace(hash) ⇒ Object
77
78
79
80
81
82
|
# File 'lib/tmsu_file_db.rb', line 77
def self.escape_hash_whitespace(hash)
hash.reduce({}) do |result, (k,v)|
result[escape_whitespace(k)] = escape_whitespace v
result
end
end
|
.escape_whitespace(string) ⇒ Object
73
74
75
|
# File 'lib/tmsu_file_db.rb', line 73
def self.escape_whitespace(string)
string.to_s.gsub(/(?<!\\)\s/, '\ ')
end
|
.find_by(opts) ⇒ Object
65
66
67
|
# File 'lib/tmsu_file_db.rb', line 65
def self.find_by opts
where(opts).first
end
|
.from_file(path) ⇒ Object
84
85
86
|
# File 'lib/tmsu_file_db.rb', line 84
def self.from_file(path)
new(escape_hash_whitespace TmsuRuby.file(path).tags) { path }
end
|
.generate_path(within: '.') ⇒ Object
24
25
26
27
28
29
|
# File 'lib/tmsu_file_db.rb', line 24
def self.generate_path(within: '.')
loop do
path = "#{within}/#{SecureRandom.hex}"
break path unless File.exists?(path)
end
end
|
.opts_to_query(opts) ⇒ Object
50
51
52
53
54
55
56
57
58
59
|
# File 'lib/tmsu_file_db.rb', line 50
def self.opts_to_query opts
case opts
when Array
opts.map { |opt| escape_whitespace opt }.join " "
when Hash
opts.map do |k,v|
"#{escape_whitespace k}=#{escape_whitespace v}"
end.join(" ")
end
end
|
.query(string) ⇒ Object
92
93
94
|
# File 'lib/tmsu_file_db.rb', line 92
def self.query string
TmsuRuby.file(query_glob).files(string).map &method(:from_file)
end
|
.query_glob ⇒ Object
16
17
18
|
# File 'lib/tmsu_file_db.rb', line 16
def self.query_glob
"#{root_path}/*"
end
|
.root_path ⇒ Object
20
21
22
|
# File 'lib/tmsu_file_db.rb', line 20
def self.root_path
Config[:root_path] || generate_path(within: "./db")
end
|
.update_all(opts = {}) ⇒ Object
96
97
98
99
100
101
102
103
104
105
106
|
# File 'lib/tmsu_file_db.rb', line 96
def self.update_all opts={}
Dir.glob(query_glob).each do |path|
errors = from_file(path).tap { |inst| inst.update(opts) }.errors
unless errors.empty?
raise(
ArgumentError, "couldn't update all. Path #{path} caused errors: #{errors.join(", ")}"
)
end
end
true
end
|
.validate(attribute = :generic, &blk) ⇒ Object
38
39
40
41
42
43
44
|
# File 'lib/tmsu_file_db.rb', line 38
def self.validate(attribute=:generic, &blk)
if attribute == :generic
Validations[:generic] << blk
else
Validations[attribute] << blk
end
end
|
.where(opts = {}) ⇒ Object
69
70
71
|
# File 'lib/tmsu_file_db.rb', line 69
def self.where opts={}
query opts_to_query opts
end
|
Instance Method Details
#[](k) ⇒ Object
143
144
145
|
# File 'lib/tmsu_file_db.rb', line 143
def [](k)
attributes[k]
end
|
#[]=(k, v) ⇒ Object
139
140
141
|
# File 'lib/tmsu_file_db.rb', line 139
def []=(k,v)
attributes[k] = v
end
|
#append(text) ⇒ Object
165
166
167
168
|
# File 'lib/tmsu_file_db.rb', line 165
def append(text)
write(text, append: true)
self
end
|
#build_path ⇒ Object
133
134
135
136
137
|
# File 'lib/tmsu_file_db.rb', line 133
def build_path
self.class.generate_path(
within: self.class::Config[:root_path] || "."
)
end
|
#delete(attr) ⇒ Object
232
233
234
235
236
237
238
239
240
|
# File 'lib/tmsu_file_db.rb', line 232
def delete(attr)
if attributes[attr].nil?
untag(attr)
else
val = attributes[attr]
untag("#{attr}=#{val}")
end
attributes.delete attr
end
|
#destroy ⇒ Object
225
226
227
228
229
230
|
# File 'lib/tmsu_file_db.rb', line 225
def destroy
`tmsu-fs-rm #{path}`
`rm #{path}`
@persisted = false
self
end
|
#ensure_persisted ⇒ Object
192
193
194
|
# File 'lib/tmsu_file_db.rb', line 192
def ensure_persisted
`touch #{path}` unless persisted?
end
|
#ensure_root_path ⇒ Object
126
127
128
129
130
131
|
# File 'lib/tmsu_file_db.rb', line 126
def ensure_root_path
unless @root_dir_created
`mkdir -p #{self.class.root_path}`
@root_dir_created = true
end
end
|
#persisted? ⇒ Boolean
188
189
190
|
# File 'lib/tmsu_file_db.rb', line 188
def persisted?
!!@persisted
end
|
#save ⇒ Object
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
# File 'lib/tmsu_file_db.rb', line 196
def save
ensure_persisted
ensure_root_path
original_attributes = tags
attributes.each do |k,v|
if !v.nil? && !(original_attributes[k] == v)
untag "#{k}=#{original_attributes[k]}"
end
end
return false unless valid?
tag attributes
@persisted = true
@attributes = tags.with_indifferent_access
true
end
|
#update(attrs = {}) ⇒ Object
212
213
214
215
216
217
218
219
220
221
222
223
|
# File 'lib/tmsu_file_db.rb', line 212
def update attrs={}
original_attrs = attributes.clone
attrs.each_key { |k| self[k] = attrs[k] }
unless valid?
self.attributes.clear
original_attrs.each { |k,v| self[k] = v }
return false
end
save
true
end
|
#valid? ⇒ Boolean
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
# File 'lib/tmsu_file_db.rb', line 170
def valid?
@errors = []
Validations.each do |type, procs|
procs.each do |proc|
some_errors = if type.eql?(:generic)
proc.call self
else
proc.call self[type], self
end
raise(
ArgumentError, "validations must return arrays"
) unless some_errors.is_a?(Array)
@errors.concat some_errors
end
end
@errors.empty?
end
|
#write(text, append: false) ⇒ Object
159
160
161
162
163
|
# File 'lib/tmsu_file_db.rb', line 159
def write(text, append: false)
return unless text
File.open(path, "w#{"a" if append}") { |f| f.write text }
self
end
|