scout-gear 10.2.0 → 10.4.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e807e8eea8b8ff3b40be002fcd9cdfa9fbc8d3fdb447f20b1b3c56f1c318de8
4
- data.tar.gz: 8838111c9867b63671060c82b7224f2ac310b64d375f0cc62c26b42092da6f1d
3
+ metadata.gz: 4e4dbf9f73608dbc264f7f7584af04ac87bbeb2175b04a7ef50d2ef72cea8592
4
+ data.tar.gz: d423876c0f4cd1132128c519e9576afa7933f5c2f50b2f3498009a7dcba8ea30
5
5
  SHA512:
6
- metadata.gz: 2dcc68c9d612b208d6b6b94dd366ef37f2467b364d1da8367b1f6833d305d6ef8c35a1dc0f0e27c6e00ce481344e230e20ac6eb85236dd27c75c59e8ad3f0ec5
7
- data.tar.gz: 85d8e7458a1453966e2e123fc8ced3a0c2bc8be884a7570f1bb57f4d260db582e90380d2ea0f8a91c91b68decb8439e8b556d294b9d71258c522fa06628ec22b
6
+ metadata.gz: 8d53af5f2c84362e664ff33f0afafafd5bb92756e5843c68466b81b09b51830a03a99093c18103a3f6a7d26a70099a283fc4841c346b223691b9afd6774399ac
7
+ data.tar.gz: 3c3fbc75f0ad79395211eb198198aa5e6e31de6e00a5d54375cfff5197d5cacfb6e0755889d157e4671b43edbbb1535b020814881df83a34227d231c623b0461
data/.vimproject CHANGED
@@ -74,7 +74,6 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
74
74
  tsv=tsv{
75
75
  util.rb
76
76
  util=util{
77
- process.rb
78
77
  select.rb
79
78
  process.rb
80
79
  unzip.rb
@@ -89,9 +88,8 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
89
88
  persist=persist{
90
89
  adapter.rb
91
90
  serialize.rb
92
- sdbm.rb
93
- tkrzw.rb
94
91
  tokyocabinet.rb
92
+ tkrzw.rb
95
93
  fix_width_table.rb
96
94
  }
97
95
  index.rb
data/VERSION CHANGED
@@ -1 +1 @@
1
- 10.2.0
1
+ 10.4.0
@@ -40,12 +40,18 @@ module TSV
40
40
 
41
41
  def self.attach(source, other, target: nil, fields: nil, match_key: nil, other_key: nil, one2one: true, complete: false, insitu: nil, persist_input: false, bar: nil)
42
42
  source = TSV::Transformer.new source unless TSV === source || TSV::Parser === source
43
- other = TSV.open other, persist: persist_input unless TSV === other
43
+ other = TSV::Parser.new other unless TSV === other || TSV::Parser === other
44
44
 
45
45
  fields = [fields] if String === fields
46
46
 
47
47
  match_key, other_key = TSV.match_keys(source, other, match_key: match_key, other_key: other_key)
48
48
 
49
+ if ! (TSV === other)
50
+ other_key_name = other_key == :key ? other.key_field : other.fields[other_key]
51
+ other = TSV.open other, key_field: other_key_name, fields: fields, one2one: true, persist: persist_input
52
+ other_key = :key if other.key_field == source.key_field
53
+ end
54
+
49
55
  if TSV::Transformer === source
50
56
  source.dumper = case target
51
57
  when :stream
@@ -117,6 +123,7 @@ module TSV
117
123
  current_values[overlap] = v if current_values[overlap].nil? || String === current_values[overlap] && current_values[overlap].empty?
118
124
  else
119
125
  current_values[overlap] ||= []
126
+ next if v.nil?
120
127
  current_values[overlap].concat (v - current_values[overlap])
121
128
  end
122
129
  end
@@ -154,6 +161,7 @@ module TSV
154
161
  end
155
162
 
156
163
  other_values.zip(overlaps).each do |v,overlap|
164
+ next if v.nil?
157
165
  if false && overlap == :key
158
166
  other_key = Array === v ? v : v.first
159
167
  elsif source.type == :list
@@ -1,10 +1,10 @@
1
1
  module TSV
2
- def self.change_key(source, new_key_field, identifiers: nil, one2one: false, stream: false, keep: false, persist_identifiers: nil)
2
+ def self.change_key(source, new_key_field, identifiers: nil, one2one: false, merge: true, stream: false, keep: false, persist_identifiers: nil)
3
3
  source = TSV::Parser.new source if String === source
4
4
  if identifiers && source.identify_field(new_key_field, strict: true).nil?
5
5
  identifiers = identifiers.nil? ? source.identifiers : identifiers
6
6
  new = source.attach(identifiers, fields: [new_key_field], insitu: false, one2one: true, persist_input: persist_identifiers)
7
- new = new.change_key(new_key_field, keep: keep, stream: stream, one2one: one2one)
7
+ new = new.change_key(new_key_field, keep: keep, stream: stream, one2one: one2one, merge: merge)
8
8
  return new
9
9
  end
10
10
 
@@ -17,7 +17,7 @@ module TSV
17
17
  [k, v]
18
18
  end
19
19
 
20
- stream ? transformer : transformer.tsv
20
+ stream ? transformer : transformer.tsv(merge: merge, one2one: one2one)
21
21
  end
22
22
 
23
23
  def change_key(*args, **kwargs)
@@ -2,7 +2,7 @@ require_relative 'parser'
2
2
  require_relative 'transformer'
3
3
  require_relative 'persist/fix_width_table'
4
4
  module TSV
5
- def self.index(tsv_file, target: 0, fields: nil, order: true, bar: nil, **kwargs)
5
+ def self.index(tsv_file, target: :key, fields: nil, order: true, bar: nil, **kwargs)
6
6
  persist, type, persist_update, data_persist = IndiferentHash.process_options kwargs,
7
7
  :persist, :persist_type, :persist_update, :data_persist,
8
8
  :persist => false, :persist_type => "HDB"
@@ -10,7 +10,7 @@ module TSV
10
10
 
11
11
  fields = :all if fields.nil?
12
12
 
13
- Persist.persist(tsv_file, type, kwargs.merge(target: target, fields: fields, persist: persist, update: persist_update, :prefix => "Index", :other_options => kwargs)) do |filename|
13
+ Persist.persist(tsv_file, type, kwargs.merge(target: target, fields: fields, persist: persist, update: persist_update, prefix: "Index", other_options: {fields: fields, target: target, order: order})) do |filename|
14
14
  if filename
15
15
  index = ScoutCabinet.open(filename, true, type)
16
16
  TSV.setup(index, :type => :single)
@@ -276,6 +276,7 @@ module TSV
276
276
  end
277
277
  @fix = fix
278
278
  @options, @key_field, @fields, @first_line, @preamble = TSV.parse_header(@stream, fix:fix, header_hash:header_hash, sep:sep)
279
+ @options[:filename] = file if Path.is_filename?(file)
279
280
  @options[:sep] = sep if @options[:sep].nil?
280
281
  @options.merge!(:key_field => @key_field, :fields => @fields)
281
282
  @type = @options[:type] || type
@@ -374,7 +375,7 @@ module TSV
374
375
  end
375
376
 
376
377
  def self.parse(stream, fix: true, header_hash: "#", sep: "\t", filename: nil, namespace: nil, unnamed: false, serializer: nil, **kwargs, &block)
377
- parser = TSV::Parser.new stream, fix: fix, header_hash: header_hash, sep: sep
378
+ parser = TSV::Parser === stream ? stream : TSV::Parser.new(stream, fix: fix, header_hash: header_hash, sep: sep)
378
379
 
379
380
  cast = kwargs[:cast]
380
381
  cast = parser.options[:cast] if cast.nil?
@@ -407,8 +408,9 @@ module TSV
407
408
 
408
409
  data = parser.traverse **kwargs, &block
409
410
  data.type = type
410
- data.filename = filename
411
- data.namespace = namespace
411
+ data.filename = filename || parser.options[:filename]
412
+ data.namespace = namespace || parser.options[:namespace]
413
+ data.identifiers = parser.options[:identifiers]
412
414
  data.unnamed = unnamed
413
415
  data.save_extension_attr_hash if data.respond_to?(:save_extension_attr_hash)
414
416
  data
@@ -0,0 +1,84 @@
1
+ require 'tkrzw'
2
+ require_relative 'adapter'
3
+
4
+ module ScoutTKRZW
5
+ attr_accessor :persistence_path, :persistence_class, :open_options
6
+
7
+ def self.open(path, write = true, persistence_class = 'tkh', options = {})
8
+ open_options = IndiferentHash.add_defaults options, truncate: true, num_buckets: 100, dbm: "HashDBM", sync_hard: true, encoding: "UTF-8"
9
+
10
+ path = path.find if Path === path
11
+
12
+ dir = File.dirname(File.expand_path(path))
13
+ Open.mkdir(dir) unless File.exist?(dir)
14
+
15
+ database = Persist::CONNECTIONS[[persistence_class, path]*":"] ||= Tkrzw::DBM.new
16
+
17
+ database.close if database.open?
18
+
19
+ database.open(path, write, open_options)
20
+
21
+ database.extend ScoutTKRZW
22
+ database.persistence_path ||= path
23
+ database.open_options = open_options
24
+
25
+ #Persist::CONNECTIONS[[persistence_class, path]*":"] = database
26
+
27
+ database
28
+ end
29
+
30
+ def close
31
+ @closed = true
32
+ @writable = false
33
+ super
34
+ end
35
+
36
+ def read(force = false)
37
+ return if open? && ! writable? && ! force
38
+ self.close if open?
39
+ if !self.open(@persistence_path, false, @open_options)
40
+ ecode = self.ecode
41
+ raise "Open error: #{self.errmsg(ecode)}. Trying to open file #{@persistence_path}"
42
+ end
43
+
44
+ @writable = false
45
+ @closed = false
46
+
47
+ self
48
+ end
49
+
50
+ def write(force = true)
51
+ return if open? && writable? && ! force
52
+ self.close if self.open?
53
+
54
+ if !self.open(@persistence_path, true, @open_options)
55
+ ecode = self.ecode
56
+ raise "Open error: #{self.errmsg(ecode)}. Trying to open file #{@persistence_path}"
57
+ end
58
+
59
+ @writable = true
60
+ @closed = false
61
+
62
+ self
63
+ end
64
+
65
+ def keys
66
+ search("contain", "")
67
+ end
68
+ end
69
+
70
+ Persist.save_drivers[:tkh] = proc do |file, content|
71
+ data = ScoutTKRZW.open(file, true, "tkh")
72
+ content.annotate(data)
73
+ data.extend TSVAdapter
74
+ data.merge!(content)
75
+ data.close
76
+ data.read
77
+ data
78
+ end
79
+
80
+ Persist.load_drivers[:tkh] = proc do |file|
81
+ data = ScoutTKRZW.open(file, false, "tkh")
82
+ data.extend TSVAdapter unless TSVAdapter === data
83
+ data
84
+ end
@@ -1,6 +1,15 @@
1
1
  require 'scout/persist'
2
2
  require_relative 'persist/adapter'
3
- require_relative 'persist/tokyocabinet'
3
+
4
+ begin
5
+ require_relative 'persist/tokyocabinet'
6
+ rescue Exception
7
+ end
8
+
9
+ begin
10
+ require_relative 'persist/tkrzw'
11
+ rescue Exception
12
+ end
4
13
 
5
14
  Persist.save_drivers[:tsv] = proc do |file,content|
6
15
  stream = if IO === content
@@ -130,6 +130,27 @@ module TSV
130
130
  res
131
131
  end
132
132
 
133
+ def to_double
134
+ return self if self.type == :double
135
+ res = self.annotate({})
136
+ self.with_unnamed do
137
+ transformer = Transformer.new self, res
138
+ transformer.type = :double
139
+ transformer.traverse do |k,v|
140
+ case self.type
141
+ when :single
142
+ [k, [[v]]]
143
+ when :list
144
+ [k, v.collect{|v| [v] }]
145
+ when :flat
146
+ [k, [v]]
147
+ end
148
+ end
149
+ end
150
+ res
151
+ end
152
+
153
+
133
154
  def to_single
134
155
  res = self.annotate({})
135
156
  transformer = Transformer.new self, res
@@ -46,7 +46,7 @@ module TSV
46
46
  def add_field(name = nil)
47
47
  through do |key, values|
48
48
  new_values = yield(key, values)
49
- new_values = [new_values] if type == :double and not Array === new_values
49
+ new_values = [new_values].compact if type == :double and not Array === new_values
50
50
 
51
51
  case
52
52
  when (values.nil? and (fields.nil? or fields.empty?))
data/lib/scout/tsv.rb CHANGED
@@ -28,22 +28,75 @@ module TSV
28
28
  {:key_field => key, :fields => fields}.merge(rest_options)
29
29
  end
30
30
 
31
+ class << self
32
+ alias original_setup setup
33
+
34
+ def setup(obj, *rest, &block)
35
+
36
+ if rest.length == 1 && String === rest.first
37
+ options = TSV.str2options(rest.first)
38
+ if Array === obj
39
+ default_value = case options[:type]
40
+ when :double, :flat, :list, nil
41
+ []
42
+ when :single
43
+ nil
44
+ end
45
+ obj = Misc.array2hash(obj, default_value)
46
+ end
47
+ original_setup(obj, options, &block)
48
+ else
49
+ if Array === obj
50
+ options = rest.first if Hash === rest.first
51
+ options ||= {}
52
+ default_value = case options[:type]
53
+ when :double, :flat, :list, nil
54
+ []
55
+ when :single
56
+ nil
57
+ end
58
+ obj = Misc.array2hash(obj, default_value)
59
+ end
60
+ original_setup(obj, *rest, &block)
61
+ end
62
+ end
63
+ end
64
+
31
65
  def self.str_setup(option_str, obj)
32
66
  options = TSV.str2options(option_str)
33
- setup(obj, options)
67
+ setup(obj, **options)
34
68
  end
35
69
 
36
70
  def self.open(file, options = {})
37
71
  grep, invert_grep = IndiferentHash.process_options options, :grep, :invert_grep, :persist => false
38
72
 
39
73
  persist_options = IndiferentHash.pull_keys options, :persist
40
- persist_options = IndiferentHash.add_defaults persist_options, :prefix => "TSV", :type => "HDB"
74
+ persist_options = IndiferentHash.add_defaults persist_options, :prefix => "TSV", :type => :HDB
41
75
 
42
76
  file = StringIO.new file if String === file && ! (Path === file) && file.index("\n")
43
- Persist.persist(file, persist_options[:type], persist_options.merge(:other_options => options)) do |filename|
44
- data = filename ? ScoutCabinet.open(filename, true, persist_options[:type]) : nil
77
+
78
+ source_name, other_options = case file
79
+ when StringIO
80
+ [file.inspect, options]
81
+ when TSV::Parser
82
+ [file.options[:filename], file.options]
83
+ else
84
+ [file, options]
85
+ end
86
+
87
+ Persist.persist(source_name, persist_options[:type], persist_options.merge(:other_options => other_options)) do |filename|
88
+ if filename
89
+ data = case persist_options[:type]
90
+ when :HDB, :BDB
91
+ ScoutCabinet.open(filename, true, persist_options[:type])
92
+ when :tkh, :tkt, :tks
93
+ ScoutTKRZW.open(filename, true, persist_options[:type])
94
+ end
95
+ else
96
+ data = nil
97
+ end
45
98
  options[:data] = data if data
46
- options[:filename] = file
99
+ options[:filename] = TSV::Parser === file ? file.options[:filename] : file
47
100
 
48
101
  if data
49
102
  Log.debug "TSV open #{Log.fingerprint file} into #{Log.fingerprint data}"
@@ -51,8 +104,12 @@ module TSV
51
104
  Log.debug "TSV open #{Log.fingerprint file}"
52
105
  end
53
106
 
54
- Open.open(file, grep: grep, invert_grep: invert_grep) do |f|
55
- TSV.parse(f, **options)
107
+ if TSV::Parser === file
108
+ TSV.parse(file, **options)
109
+ else
110
+ Open.open(file, grep: grep, invert_grep: invert_grep) do |f|
111
+ TSV.parse(f, **options)
112
+ end
56
113
  end
57
114
  end
58
115
  end
@@ -103,11 +103,18 @@ module Workflow
103
103
  end
104
104
 
105
105
  def task(name_and_type, &block)
106
- name, type = name_and_type.collect.first
106
+ case name_and_type
107
+ when Hash
108
+ name, type = name_and_type.collect.first
109
+ when Symbol
110
+ name, type = [name_and_type, :binary]
111
+ when String
112
+ name, type = [name_and_type, :binary]
113
+ end
107
114
  type = type.to_sym if String === type
108
115
  name = name.to_sym if String === name
109
116
  @tasks ||= IndiferentHash.setup({})
110
- block = self.method(name) if block.nil?
117
+ block = lambda &self.method(name) if block.nil?
111
118
  begin
112
119
  @annotate_next_task ||= {}
113
120
  @annotate_next_task[:extension] ||=
@@ -137,7 +144,7 @@ module Workflow
137
144
  dep(workflow, oname, *rest, &block)
138
145
  extension :dep_task unless @extension
139
146
  task_proc = workflow.tasks[oname]
140
- raise "Task #{name} not found" if task_proc.nil?
147
+ raise "Task #{oname} not found" if task_proc.nil?
141
148
  returns task_proc.returns if @returns.nil?
142
149
  type = task_proc.type
143
150
  task name => type do
@@ -19,7 +19,7 @@ module Task
19
19
  step_inputs.each do |k,v|
20
20
  if Symbol === v
21
21
  input_dep = dependencies.select{|d| d.task_name == v }.first
22
- resolved_inputs[k] = input_dep || step_inputs[v] || k
22
+ resolved_inputs[k] = input_dep || provided_inputs[v] || step_inputs[v] || k
23
23
  else
24
24
  resolved_inputs[k] = v
25
25
  end
@@ -79,7 +79,7 @@ module Task
79
79
  when Step
80
80
  dep = res
81
81
  dependencies << dep
82
- dep_non_default_inputs = find_dep_non_default_inputs.call(dep, block_options)
82
+ dep_non_default_inputs = find_dep_non_default_inputs.call(dep, definition_options)
83
83
  non_default_inputs.concat(dep_non_default_inputs)
84
84
  when Hash
85
85
  step_options = block_options.merge(res)
@@ -3,7 +3,7 @@ module Task
3
3
  def self.format_input(value, type, options = {})
4
4
  return value if IO === value || StringIO === value || Step === value
5
5
 
6
- if String === value && ! [:path, :file, :folder, :binary].include?(type) && ! (options && (options[:noload] || options[:stream] || options[:nofile]))
6
+ if String === value && ! [:path, :file, :folder, :binary, :tsv].include?(type) && ! (options && (options[:noload] || options[:stream] || options[:nofile]))
7
7
  if Open.exists?(value) && ! Open.directory?(value)
8
8
  Persist.load(value, type)
9
9
  else
data/scout-gear.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: scout-gear 10.2.0 ruby lib
5
+ # stub: scout-gear 10.4.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "scout-gear".freeze
9
- s.version = "10.2.0"
9
+ s.version = "10.4.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Miguel Vazquez".freeze]
14
- s.date = "2023-07-27"
14
+ s.date = "2023-08-09"
15
15
  s.description = "Temporary files, logs, path, resources, persistence, workflows, TSV, etc.".freeze
16
16
  s.email = "mikisvaz@gmail.com".freeze
17
17
  s.executables = ["scout".freeze]
@@ -51,6 +51,7 @@ Gem::Specification.new do |s|
51
51
  "lib/scout/tsv/persist/adapter.rb",
52
52
  "lib/scout/tsv/persist/fix_width_table.rb",
53
53
  "lib/scout/tsv/persist/serialize.rb",
54
+ "lib/scout/tsv/persist/tkrzw.rb",
54
55
  "lib/scout/tsv/persist/tokyocabinet.rb",
55
56
  "lib/scout/tsv/stream.rb",
56
57
  "lib/scout/tsv/transformer.rb",
@@ -124,6 +125,7 @@ Gem::Specification.new do |s|
124
125
  "test/scout/test_workflow.rb",
125
126
  "test/scout/tsv/persist/test_adapter.rb",
126
127
  "test/scout/tsv/persist/test_fix_width_table.rb",
128
+ "test/scout/tsv/persist/test_tkrzw.rb",
127
129
  "test/scout/tsv/persist/test_tokyocabinet.rb",
128
130
  "test/scout/tsv/test_attach.rb",
129
131
  "test/scout/tsv/test_change_id.rb",
@@ -310,6 +310,9 @@ row2 b bbb bbbb bb
310
310
 
311
311
  tsv = TSV.str_setup("ID~ValueA,ValueB#:type=:flat", {})
312
312
  assert_equal "ID", tsv.key_field
313
+
314
+ tsv = TSV.setup({}, "ID~ValueA,ValueB#:type=:flat")
315
+ assert_equal "ID", tsv.key_field
313
316
  end
314
317
 
315
318
  def test_cast_in_header
@@ -328,4 +331,31 @@ c 3
328
331
  assert_include tsv.to_s, ":cast=:to_f"
329
332
  end
330
333
  end
334
+
335
+ def test_open_persist_parser
336
+ content =<<-'EOF'
337
+ #: :sep=/\s+/#:type=:double#:merge=:concat
338
+ #Id ValueA ValueB OtherID
339
+ row1 a|aa|aaa b Id1|Id2
340
+ row2 A B Id3
341
+ row2 a a id3
342
+ EOF
343
+
344
+ tsv = TmpFile.with_file(content) do |filename|
345
+ parser = TSV::Parser.new filename
346
+ tsv = TSV.open(parser, :persist => true)
347
+ tsv.close
348
+ Persist::CONNECTIONS.clear
349
+ TSV.open(filename, :persist => true)
350
+ end
351
+
352
+ assert_equal "Id", tsv.key_field
353
+
354
+ assert tsv.respond_to?(:persistence_class)
355
+ assert_equal TokyoCabinet::HDB, tsv.persistence_class
356
+
357
+ assert_include tsv.keys, 'row1'
358
+ assert_include tsv.keys, 'row2'
359
+ end
360
+
331
361
  end
@@ -0,0 +1,129 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+
3
+ require 'scout/tsv'
4
+
5
+ begin
6
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
7
+ class TestScoutTKRZW < Test::Unit::TestCase
8
+ def setup
9
+ end
10
+
11
+ def test_open
12
+ TmpFile.with_file nil do |tmp|
13
+ db = ScoutTKRZW.open(tmp, true)
14
+ 1000.times do |i|
15
+ db["foo#{i}"] = "bar#{i}"
16
+ end
17
+ assert_include db, 'foo1'
18
+ assert_equal 1000, db.keys.length
19
+
20
+ db.close
21
+ TmpFile.with_file nil do |tmp_alt|
22
+ Open.cp tmp, tmp_alt
23
+ db2 = ScoutTKRZW.open(tmp_alt, false)
24
+ assert_include db2, 'foo1'
25
+ assert_equal 1000, db2.keys.length
26
+ end
27
+ end
28
+ end
29
+
30
+ def test_tkrzw
31
+ content =<<-'EOF'
32
+ #: :sep=/\s+/#:type=:double#:merge=:concat
33
+ #Id ValueA ValueB OtherID
34
+ row1 a|aa|aaa b Id1|Id2
35
+ row2 A B Id3
36
+ row2 a a id3
37
+ EOF
38
+
39
+ tsv = TmpFile.with_file(content) do |filename|
40
+ Persist.persist(__method__, 'tkh') do
41
+ TSV.open(filename)
42
+ end
43
+ end
44
+
45
+
46
+ assert_equal %w(a aa aaa), tsv["row1"][0]
47
+
48
+ assert TSVAdapter === tsv
49
+ assert TSV === tsv
50
+ assert_include tsv.instance_variable_get(:@extension_attrs), :key_field
51
+ assert_include tsv.instance_variable_get(:@extension_attrs), :serializer
52
+
53
+ tsv.close
54
+ tsv_loaded = assert_nothing_raised do
55
+ TmpFile.with_file(content) do |filename|
56
+ Persist.persist(__method__, 'tkh') do
57
+ raise
58
+ end
59
+ end
60
+ end
61
+
62
+ assert_equal %w(a aa aaa), tsv_loaded["row1"][0]
63
+ end
64
+
65
+ def __test_benchmark1
66
+ TmpFile.with_file nil do |tmp|
67
+
68
+ Misc.benchmark(1000) do
69
+ db = ScoutTKRZW.open(tmp, true)
70
+ 1000.times do |i|
71
+ db["foo#{i}"] = "bar#{i}"
72
+ end
73
+ 10.times do
74
+ db.keys
75
+ end
76
+ 10.times do |i|
77
+ db["foo#{i}"]
78
+ end
79
+ Open.rm tmp
80
+ end
81
+
82
+ Misc.benchmark(1000) do
83
+ db = ScoutCabinet.open(tmp, true)
84
+ 1000.times do |i|
85
+ db["foo#{i}"] = "bar#{i}"
86
+ end
87
+ 10.times do
88
+ db.keys
89
+ end
90
+ 10.times do |i|
91
+ db["foo#{i}"]
92
+ end
93
+ db.close
94
+ Open.rm tmp
95
+ end
96
+ end
97
+ end
98
+
99
+ def test_benchmark2
100
+ TmpFile.with_file nil do |tmp|
101
+
102
+ db = ScoutTKRZW.open(tmp, true)
103
+ 10000.times do |i|
104
+ db["foo#{i}"] = "bar#{i}"
105
+ end
106
+
107
+ Misc.benchmark(1000) do
108
+ 100.times do |i|
109
+ db["foo#{i}"]
110
+ end
111
+ end
112
+
113
+ Open.rm tmp
114
+ db = ScoutCabinet.open(tmp, true)
115
+ 10000.times do |i|
116
+ db["foo#{i}"] = "bar#{i}"
117
+ end
118
+ Misc.benchmark(1000) do
119
+ 100.times do |i|
120
+ db["foo#{i}"]
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ end
127
+ rescue Exception
128
+ end
129
+
@@ -117,4 +117,16 @@ row2 A2|A22 B2|B22
117
117
  tsv = TSV.open(content)
118
118
  assert_equal %w(A1 A11 B1 B11), tsv.to_flat["row1"]
119
119
  end
120
+
121
+ def test_to_double
122
+ content =<<-EOF
123
+ #: :sep=" "
124
+ #ID ValueA ValueB
125
+ row1 A1 B1
126
+ row2 A2 B2
127
+ EOF
128
+
129
+ tsv = TSV.open(content)
130
+ assert_equal %w(A1), tsv.to_double["row1"]["ValueA"]
131
+ end
120
132
  end
@@ -43,5 +43,25 @@ row2 AA BB Id33
43
43
  assert_equal %w(c cc ccc), tsv["row1"]["ValueC"]
44
44
  assert_equal %w(C CC), tsv["row2"]["ValueC"]
45
45
  end
46
+
47
+ def test_add_field_double_empty
48
+ content =<<-'EOF'
49
+ #: :sep=/\s+/#:type=:double
50
+ #Id ValueA ValueB OtherID
51
+ row1 a|aa|aaa b Id1|Id2
52
+ row2 A B Id3
53
+ row2 AA BB Id33
54
+ EOF
55
+
56
+ tsv = TmpFile.with_file(content) do |filename|
57
+ TSV.open(filename)
58
+ end
59
+
60
+ tsv.add_field "ValueC" do |k,v|
61
+ nil
62
+ end
63
+
64
+ assert_equal %w(), tsv["row1"]["ValueC"]
65
+ end
46
66
  end
47
67
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scout-gear
3
3
  version: !ruby/object:Gem::Version
4
- version: 10.2.0
4
+ version: 10.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Vazquez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-27 00:00:00.000000000 Z
11
+ date: 2023-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: scout-essentials
@@ -163,6 +163,7 @@ files:
163
163
  - lib/scout/tsv/persist/adapter.rb
164
164
  - lib/scout/tsv/persist/fix_width_table.rb
165
165
  - lib/scout/tsv/persist/serialize.rb
166
+ - lib/scout/tsv/persist/tkrzw.rb
166
167
  - lib/scout/tsv/persist/tokyocabinet.rb
167
168
  - lib/scout/tsv/stream.rb
168
169
  - lib/scout/tsv/transformer.rb
@@ -236,6 +237,7 @@ files:
236
237
  - test/scout/test_workflow.rb
237
238
  - test/scout/tsv/persist/test_adapter.rb
238
239
  - test/scout/tsv/persist/test_fix_width_table.rb
240
+ - test/scout/tsv/persist/test_tkrzw.rb
239
241
  - test/scout/tsv/persist/test_tokyocabinet.rb
240
242
  - test/scout/tsv/test_attach.rb
241
243
  - test/scout/tsv/test_change_id.rb