lucarecord 0.2.13 → 0.2.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/luca_record/io.rb +93 -120
- data/lib/luca_record/version.rb +1 -1
- data/lib/luca_support/code.rb +7 -0
- metadata +9 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b2e7e80da19b8c0adaebc6272a05e26f66c2e6a989fa416bfd77951ac5f88a0
|
4
|
+
data.tar.gz: 699708346c68e5fa32105eec0d8a82aae8fd85c452f005a402f80a9ff7b19b95
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59217fdab9258c37ceab07e35118961ae3ac6d6d1587f84235b31169dacf8a82f968a2e8b00f0710c0f7e587836d7d4834f4bf8d2f51e5fbd6f30d1a3100ea7b
|
7
|
+
data.tar.gz: edbc54ec5c66e422a6975c8e53a33b32a063304d5c582ebf4f22596151d141de7d90404eaff8cdd7e8b10264f195da67803ba48a2e4426c6629d995f6cc03507
|
data/lib/luca_record/io.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'csv'
|
2
4
|
require 'date'
|
3
5
|
require 'fileutils'
|
@@ -6,11 +8,10 @@ require 'pathname'
|
|
6
8
|
require 'luca_support/code'
|
7
9
|
require 'luca_support/config'
|
8
10
|
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
module LucaRecord
|
11
|
+
module LucaRecord # :nodoc:
|
12
|
+
# == IO
|
13
|
+
# Read / Write hash data with id and/or date.
|
14
|
+
# Manage both database & historical records.
|
14
15
|
module IO
|
15
16
|
include LucaSupport::Code
|
16
17
|
|
@@ -18,32 +19,15 @@ module LucaRecord
|
|
18
19
|
klass.extend ClassMethods
|
19
20
|
end
|
20
21
|
|
21
|
-
#
|
22
|
-
# Used @date for searching current settings
|
23
|
-
# query can be nested hash for other than 'val'
|
24
|
-
#
|
25
|
-
# where(contract_status: 'active')
|
26
|
-
# where(graded: {rank: 5})
|
27
|
-
#
|
28
|
-
def where(**query)
|
29
|
-
return enum_for(:where, **query) unless block_given?
|
30
|
-
|
31
|
-
query.each do |key, val|
|
32
|
-
v = val.respond_to?(:values) ? val.values.first : val
|
33
|
-
label = val.respond_to?(:keys) ? val.keys.first : 'val'
|
34
|
-
self.class.all do |data|
|
35
|
-
next unless data.keys.map(&:to_sym).include?(key)
|
36
|
-
|
37
|
-
processed = parse_current(data)
|
38
|
-
yield processed if v == processed.dig(key.to_s, label.to_s)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
22
|
module ClassMethods
|
44
|
-
|
23
|
+
#-----------------------------------------------------------------
|
24
|
+
# :section: Query Methods
|
25
|
+
# Provide sematic search interfaces.
|
26
|
+
# <tt>basedir</tt> is set by class instance variable <tt>@dirname</tt>
|
27
|
+
# of each concrete class.
|
28
|
+
#-----------------------------------------------------------------
|
29
|
+
|
45
30
|
# find ID based record. Support uuid and encoded date.
|
46
|
-
#
|
47
31
|
def find(id, basedir = @dirname)
|
48
32
|
return enum_for(:find, id, basedir) unless block_given?
|
49
33
|
|
@@ -61,7 +45,6 @@ module LucaRecord
|
|
61
45
|
end
|
62
46
|
end
|
63
47
|
|
64
|
-
#
|
65
48
|
# search date based record.
|
66
49
|
#
|
67
50
|
# * data hash
|
@@ -75,7 +58,6 @@ module LucaRecord
|
|
75
58
|
end
|
76
59
|
end
|
77
60
|
|
78
|
-
#
|
79
61
|
# search with date params & code.
|
80
62
|
#
|
81
63
|
def search(year, month = nil, day = nil, code = nil, basedir = @dirname)
|
@@ -91,7 +73,6 @@ module LucaRecord
|
|
91
73
|
end
|
92
74
|
end
|
93
75
|
|
94
|
-
#
|
95
76
|
# retrieve all data
|
96
77
|
#
|
97
78
|
def all(basedir = @dirname)
|
@@ -102,13 +83,53 @@ module LucaRecord
|
|
102
83
|
end
|
103
84
|
end
|
104
85
|
|
105
|
-
|
86
|
+
#-----------------------------------------------------------------
|
87
|
+
# :section: Write Methods
|
88
|
+
# <tt>basedir</tt> is set by class instance variable <tt>@dirname</tt>
|
89
|
+
# of each concrete class.
|
90
|
+
#-----------------------------------------------------------------
|
91
|
+
|
92
|
+
# create hash based record
|
93
|
+
def create(obj, basedir = @dirname)
|
94
|
+
id = LucaSupport::Code.issue_random_id
|
95
|
+
obj['id'] = id
|
96
|
+
open_hashed(basedir, id, 'w') do |f|
|
97
|
+
f.write(YAML.dump(obj.sort.to_h))
|
98
|
+
end
|
99
|
+
id
|
100
|
+
end
|
101
|
+
|
102
|
+
# define new transaction ID & write data at once
|
103
|
+
def create_record!(obj, date_obj, codes = nil, basedir = @dirname)
|
104
|
+
gen_record_file!(basedir, date_obj, codes) do |f|
|
105
|
+
f.write(YAML.dump(obj.sort.to_h))
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def prepare_dir!(basedir, date_obj)
|
110
|
+
dir_name = (Pathname(basedir) + encode_dirname(date_obj)).to_s
|
111
|
+
FileUtils.mkdir_p(dir_name) unless Dir.exist?(dir_name)
|
112
|
+
dir_name
|
113
|
+
end
|
114
|
+
|
115
|
+
def add_status!(id, status, basedir = @dirname)
|
116
|
+
path = abs_path(basedir) / id2path(id)
|
117
|
+
origin = YAML.load_file(path, {})
|
118
|
+
newline = { status => DateTime.now.to_s }
|
119
|
+
origin['status'] = [] if origin['status'].nil?
|
120
|
+
origin['status'] << newline
|
121
|
+
File.write(path, YAML.dump(origin.sort.to_h))
|
122
|
+
end
|
123
|
+
|
124
|
+
#-----------------------------------------------------------------
|
125
|
+
# :section: Path Utilities
|
126
|
+
#-----------------------------------------------------------------
|
127
|
+
|
106
128
|
# convert ID to file path. Normal argument is as follows:
|
107
129
|
#
|
108
|
-
#
|
109
|
-
#
|
110
|
-
#
|
111
|
-
#
|
130
|
+
# [2020H, V001]
|
131
|
+
# "2020H/V001"
|
132
|
+
# "a7b806d04a044c6dbc4ce72932867719"
|
112
133
|
def id2path(id)
|
113
134
|
if id.is_a?(Array)
|
114
135
|
id.join('/')
|
@@ -119,9 +140,7 @@ module LucaRecord
|
|
119
140
|
end
|
120
141
|
end
|
121
142
|
|
122
|
-
#
|
123
143
|
# Directory separation for performance. Same as Git way.
|
124
|
-
#
|
125
144
|
def encode_hashed_path(id, split_factor = 3)
|
126
145
|
len = id.length
|
127
146
|
if len <= split_factor
|
@@ -131,63 +150,22 @@ module LucaRecord
|
|
131
150
|
end
|
132
151
|
end
|
133
152
|
|
134
|
-
def
|
135
|
-
|
136
|
-
origin = YAML.load_file(path, {})
|
137
|
-
newline = { status => DateTime.now.to_s }
|
138
|
-
origin['status'] = [] if origin['status'].nil?
|
139
|
-
origin['status'] << newline
|
140
|
-
File.write(path, YAML.dump(origin.sort.to_h))
|
141
|
-
end
|
142
|
-
|
143
|
-
#
|
144
|
-
# create hash based record
|
145
|
-
#
|
146
|
-
def create(obj, basedir = @dirname)
|
147
|
-
id = LucaSupport::Code.issue_random_id
|
148
|
-
obj['id'] = id
|
149
|
-
open_hashed(basedir, id, 'w') do |f|
|
150
|
-
f.write(YAML.dump(obj.sort.to_h))
|
151
|
-
end
|
152
|
-
id
|
153
|
-
end
|
154
|
-
|
155
|
-
#
|
156
|
-
# define new transaction ID & write data at once
|
157
|
-
#
|
158
|
-
def create_record!(date_obj, codes = nil, basedir = @dirname)
|
159
|
-
gen_record_file!(basedir, date_obj, codes) do |f|
|
160
|
-
f.write CSV.generate('', col_sep: "\t", headers: false) { |c| yield(c) }
|
161
|
-
end
|
153
|
+
def encode_dirname(date_obj)
|
154
|
+
date_obj.year.to_s + LucaSupport::Code.encode_month(date_obj)
|
162
155
|
end
|
163
156
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
filename += codes.inject('') { |fragment, code| "#{fragment}-#{code}" }
|
169
|
-
end
|
170
|
-
path = Pathname(d) + filename
|
171
|
-
File.open(path.to_s, 'w') { |f| yield(f) }
|
157
|
+
# test if having required dirs/files under exec path
|
158
|
+
def valid_project?(path = LucaSupport::Config::Pjdir)
|
159
|
+
project_dir = Pathname(path)
|
160
|
+
FileTest.file?((project_dir + 'config.yml').to_s) and FileTest.directory?( (project_dir + 'data').to_s)
|
172
161
|
end
|
173
162
|
|
174
163
|
def new_record_id(basedir, date_obj)
|
175
164
|
LucaSupport::Code.encode_txid(new_record_no(basedir, date_obj))
|
176
165
|
end
|
177
166
|
|
178
|
-
def prepare_dir!(basedir, date_obj)
|
179
|
-
dir_name = (Pathname(basedir) + encode_dirname(date_obj)).to_s
|
180
|
-
FileUtils.mkdir_p(dir_name) unless Dir.exist?(dir_name)
|
181
|
-
dir_name
|
182
|
-
end
|
183
|
-
|
184
|
-
def encode_dirname(date_obj)
|
185
|
-
date_obj.year.to_s + LucaSupport::Code.encode_month(date_obj)
|
186
|
-
end
|
187
|
-
|
188
167
|
private
|
189
168
|
|
190
|
-
#
|
191
169
|
# open records with 'basedir/month/date-code' path structure.
|
192
170
|
# Glob pattern can be specified like folloing examples.
|
193
171
|
#
|
@@ -198,7 +176,6 @@ module LucaRecord
|
|
198
176
|
# 1. encoded month
|
199
177
|
# 2. encoded day + record number of the day
|
200
178
|
# 3. codes. More than 3 are all code set except first 2 parameters.
|
201
|
-
#
|
202
179
|
def open_records(basedir, subdir, filename = nil, code = nil, mode = 'r')
|
203
180
|
return enum_for(:open_records, basedir, subdir, filename, code, mode) unless block_given?
|
204
181
|
|
@@ -213,7 +190,6 @@ module LucaRecord
|
|
213
190
|
end
|
214
191
|
end
|
215
192
|
|
216
|
-
#
|
217
193
|
# git object like structure
|
218
194
|
#
|
219
195
|
def open_hashed(basedir, id, mode = 'r')
|
@@ -225,7 +201,6 @@ module LucaRecord
|
|
225
201
|
File.open((dirpath + filename).to_s, mode) { |f| yield f }
|
226
202
|
end
|
227
203
|
|
228
|
-
#
|
229
204
|
# scan through all files
|
230
205
|
#
|
231
206
|
def open_all(basedir, mode = 'r')
|
@@ -237,7 +212,6 @@ module LucaRecord
|
|
237
212
|
end
|
238
213
|
end
|
239
214
|
|
240
|
-
#
|
241
215
|
# Decode basic format.
|
242
216
|
# If specific decode is needed, override this method in each class.
|
243
217
|
#
|
@@ -253,6 +227,16 @@ module LucaRecord
|
|
253
227
|
end
|
254
228
|
end
|
255
229
|
|
230
|
+
def gen_record_file!(basedir, date_obj, codes = nil)
|
231
|
+
d = prepare_dir!(abs_path(basedir), date_obj)
|
232
|
+
filename = LucaSupport::Code.encode_date(date_obj) + new_record_id(abs_path(basedir), date_obj)
|
233
|
+
if codes
|
234
|
+
filename += codes.inject('') { |fragment, code| "#{fragment}-#{code}" }
|
235
|
+
end
|
236
|
+
path = Pathname(d) + filename
|
237
|
+
File.open(path.to_s, 'w') { |f| yield(f) }
|
238
|
+
end
|
239
|
+
|
256
240
|
# TODO: replace with data_dir method
|
257
241
|
def abs_path(base_dir)
|
258
242
|
Pathname(LucaSupport::Config::Pjdir) / 'data' / base_dir
|
@@ -282,25 +266,28 @@ module LucaRecord
|
|
282
266
|
end
|
283
267
|
end # end of ClassModules
|
284
268
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
269
|
+
# Used @date for searching current settings
|
270
|
+
# query can be nested hash for other than 'val'
|
271
|
+
#
|
272
|
+
# where(contract_status: 'active')
|
273
|
+
# where(graded: {rank: 5})
|
274
|
+
#
|
275
|
+
def where(**query)
|
276
|
+
return enum_for(:where, **query) unless block_given?
|
293
277
|
|
294
|
-
|
295
|
-
|
278
|
+
query.each do |key, val|
|
279
|
+
v = val.respond_to?(:values) ? val.values.first : val
|
280
|
+
label = val.respond_to?(:keys) ? val.keys.first : 'val'
|
281
|
+
self.class.all do |data|
|
282
|
+
next unless data.keys.map(&:to_sym).include?(key)
|
296
283
|
|
297
|
-
|
298
|
-
|
299
|
-
|
284
|
+
processed = parse_current(data)
|
285
|
+
yield processed if v == processed.dig(key.to_s, label.to_s)
|
286
|
+
end
|
287
|
+
end
|
300
288
|
end
|
301
289
|
|
302
|
-
#
|
303
|
-
# for date based records
|
290
|
+
# parse data dir and respond existing months
|
304
291
|
#
|
305
292
|
def scan_terms(base_dir, query = nil)
|
306
293
|
pattern = query.nil? ? "*" : "#{query}*"
|
@@ -313,25 +300,11 @@ module LucaRecord
|
|
313
300
|
|
314
301
|
def load_config(path = nil)
|
315
302
|
path = path.to_s
|
316
|
-
if File.
|
303
|
+
if File.exist?(path)
|
317
304
|
YAML.load_file(path, **{})
|
318
305
|
else
|
319
306
|
{}
|
320
307
|
end
|
321
308
|
end
|
322
|
-
|
323
|
-
def has_status?(dat, status)
|
324
|
-
return false if dat['status'].nil?
|
325
|
-
|
326
|
-
dat['status'].map { |h| h.key?(status) }
|
327
|
-
.include?(true)
|
328
|
-
end
|
329
|
-
|
330
|
-
def load_tsv(path)
|
331
|
-
return enum_for(:load_tsv, path) unless block_given?
|
332
|
-
|
333
|
-
data = CSV.read(path, headers: true, col_sep: "\t", encoding: 'UTF-8')
|
334
|
-
data.each { |row| yield row }
|
335
|
-
end
|
336
309
|
end
|
337
310
|
end
|
data/lib/luca_record/version.rb
CHANGED
data/lib/luca_support/code.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lucarecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chuma Takahiro
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-10-
|
11
|
+
date: 2020-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mail
|
@@ -87,12 +87,13 @@ files:
|
|
87
87
|
- lib/luca_support/config.rb
|
88
88
|
- lib/luca_support/mail.rb
|
89
89
|
- lib/luca_support/view.rb
|
90
|
-
homepage: https://github.com/chumaltd/luca/lucarecord
|
91
|
-
licenses:
|
90
|
+
homepage: https://github.com/chumaltd/luca/tree/master/lucarecord
|
91
|
+
licenses:
|
92
|
+
- GPL
|
92
93
|
metadata:
|
93
|
-
homepage_uri: https://github.com/chumaltd/luca/lucarecord
|
94
|
-
source_code_uri: https://github.com/chumaltd/luca/lucarecord
|
95
|
-
changelog_uri: https://github.com/chumaltd/luca/lucarecord/CHANGELOG.md
|
94
|
+
homepage_uri: https://github.com/chumaltd/luca/tree/master/lucarecord
|
95
|
+
source_code_uri: https://github.com/chumaltd/luca/tree/master/lucarecord
|
96
|
+
changelog_uri: https://github.com/chumaltd/luca/tree/master/lucarecord/CHANGELOG.md
|
96
97
|
post_install_message:
|
97
98
|
rdoc_options: []
|
98
99
|
require_paths:
|
@@ -101,7 +102,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
101
102
|
requirements:
|
102
103
|
- - ">="
|
103
104
|
- !ruby/object:Gem::Version
|
104
|
-
version:
|
105
|
+
version: 2.6.0
|
105
106
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
107
|
requirements:
|
107
108
|
- - ">="
|