scout-gear 10.2.0 → 10.4.0

Sign up to get free protection for your applications and to get access to all the features.
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