Class: Ccp::Persistent::Tsv

Inherits:
Dir
  • Object
show all
Defined in:
lib/ccp/persistent/tsv.rb

Instance Attribute Summary

Attributes inherited from Base

#serializer, #source

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Dir

#exist?, #load, #path

Methods inherited from Base

#[], #exist?, #initialize, #load, #read, #read!, #save

Constructor Details

This class inherits a constructor from Ccp::Persistent::Base

Class Method Details

.extObject



4
5
6
# File 'lib/ccp/persistent/tsv.rb', line 4

def self.ext
  "tsv"
end

Instance Method Details

#[]=(key, val) ⇒ Object



74
75
76
77
78
79
80
81
82
# File 'lib/ccp/persistent/tsv.rb', line 74

def []=(key, val)
  # Now, tsv can manage only hash
  case val
  when Hash
    tsv_path_for(key).open("w+"){|f| save_tsv(f, val)}
  else
    super
  end
end

#filesObject



84
85
86
# File 'lib/ccp/persistent/tsv.rb', line 84

def files
  Dir["#{path}/*.#{ext}"] + Dir["#{path}/*.#{ext}.#{self.class.ext}"]
end

#keysObject



88
89
90
# File 'lib/ccp/persistent/tsv.rb', line 88

def keys
  files.map{|i| File.basename(i).split(".").first}.sort
end

#load!(key) ⇒ Object



63
64
65
66
67
68
69
70
71
72
# File 'lib/ccp/persistent/tsv.rb', line 63

def load!(key)
  path = path_for(key)
  if path.exist?
    super
  elsif (tsv = tsv_path_for(key)).exist?
    load_tsv(tsv)
  else
    super
  end
end

#load_tsv(path) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/ccp/persistent/tsv.rb', line 8

def load_tsv(path)
  hash = {}
  prev = []

  path.readlines.each_with_index do |line, i|
    no = i+1
    key, val = line.split(/\t/,2)

    if val
      # flush previous line
      if prev.size == 2
        hash[prev[0]] = decode(prev[1])
        prev = []
      end

      # push prev line
      prev = [key, val]

    else
      # maybe sequencial lines for one value
      if prev.size == 2
        prev[1] = prev[1] + "\n" + key

      else
        $stderr.puts "#{self.class}#load_tsv: value not found. key='#{key}' (line: #{no})"
        next
      end
    end
  end

  # flush last line
  if prev.size == 2
    hash[prev[0]] = decode(prev[1])
  end

  return hash
end

#save_tsv(f, hash) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/ccp/persistent/tsv.rb', line 46

def save_tsv(f, hash)
  keys = hash.keys
  keys =
    case keys.first
    when NilClass ; return
    when Symbol   ; keys
    when /\A\d+\Z/; keys.sort_by(&:to_i)
    when String   ; keys.sort
    else          ; keys
    end

  keys.each do |key|
    value = encode(hash[key]).sub(/\n+\Z/m, '') # strip last LF for human-readability
    f.puts "%s\t%s\n" % [key, value]
  end
end

#truncateObject



92
93
94
# File 'lib/ccp/persistent/tsv.rb', line 92

def truncate
  files.each{|file| File.unlink(file)}
end

#tsv_path_for(key) ⇒ Object



96
97
98
# File 'lib/ccp/persistent/tsv.rb', line 96

def tsv_path_for(key)
  Pathname(path_for(key).to_s + ".tsv")
end