Handbuch-Beispiele als Test, search/seek mit Schlüsseltabelle
- doc/handbuch.txt: OCR-Text des COHERENT-/rdb-Handbuchs - demo/handbuch/ und test/handbuch_test.rb: Beispiele aus dem Lehrbuchteil, mise run test führt sie mit aus - search/seek: Schlüsselspalten aus dem Kopf der Schlüsseltabelle - gregorian -u ohne führende Null im Monat, mean ganzzahlig ohne .00 - Mit justify aufgefüllte Spaltennamen werden wieder gefunden - coherent.pdf in .gitignore
This commit is contained in:
+25
-6
@@ -3,6 +3,7 @@
|
||||
# Finding, adding, changing and locking records. Many of these take the name
|
||||
# of the table instead of reading it on stdin, because they change the file.
|
||||
|
||||
require 'stringio'
|
||||
require_relative '../fast'
|
||||
|
||||
# Parse the common fast-access options. Stops at the first non-option, which
|
||||
@@ -30,8 +31,26 @@ def need_index(table, method)
|
||||
Rdb.die("no index #{table}#{suffix}: run index -m#{method} #{table}")
|
||||
end
|
||||
|
||||
def each_key(ncols)
|
||||
if $stdin.tty?
|
||||
# The key columns and, unless keys come from the terminal, the keys. Without key
|
||||
# columns on the command line a key table names them in its head line
|
||||
# (handbook p. 105: "search -mh mailtable < name"); otherwise the first column.
|
||||
def key_columns(args, data)
|
||||
return [args.empty? ? [data.head[0]] : args, nil] if $stdin.tty?
|
||||
|
||||
text = $stdin.read.to_s
|
||||
lines = text.lines.map { |l| l.chomp("\n") }
|
||||
cols = args
|
||||
if cols.empty?
|
||||
keyed = lines.size >= 2 && Rdb::Table.dash_line?(lines[1].split("\t", -1))
|
||||
cols = keyed ? lines[0].split("\t", -1).map(&:strip) : [data.head[0]]
|
||||
end
|
||||
[cols, Rdb::Fast.read_keys(StringIO.new(text), cols.size)]
|
||||
end
|
||||
|
||||
def each_key(ncols, keys = nil, &block)
|
||||
if keys
|
||||
keys.each(&block)
|
||||
elsif $stdin.tty?
|
||||
$stdin.each_line { |l| yield l.chomp.split("\t", -1).first(ncols) }
|
||||
else
|
||||
Rdb::Fast.read_keys($stdin, ncols).each { |k| yield k }
|
||||
@@ -56,9 +75,9 @@ Rdb.register('search', 'Search a table',
|
||||
table = args.shift or die 'usage: search [-m[bhirs]] table [keycolumn ...] < keys'
|
||||
data = Rdb::Fast::Data.new(table)
|
||||
need_index(table, o[:m])
|
||||
keycols = args.empty? ? [data.head[0]] : args
|
||||
keycols, keys = key_columns(args, data)
|
||||
puts data.head.join("\t"), Rdb::Table.dash_row(data.head) unless o[:h]
|
||||
each_key(keycols.size) do |key|
|
||||
each_key(keycols.size, keys) do |key|
|
||||
hits = Rdb::Fast.search(data, o[:m], keycols, key, first: o[:s] || o[:l], partial: o[:x], exact: o[:exact])
|
||||
hits.each do |h|
|
||||
puts h.row.line
|
||||
@@ -73,8 +92,8 @@ Rdb.register('seek', 'Return the beginning and ending offset of a row', 'seek [-
|
||||
table = args.shift or die 'usage: seek [-m] [-o outfile] table [keycolumn ...]'
|
||||
data = Rdb::Fast::Data.new(table)
|
||||
need_index(table, o[:m])
|
||||
keycols = args.empty? ? [data.head[0]] : args
|
||||
each_key(keycols.size) do |key|
|
||||
keycols, keys = key_columns(args, data)
|
||||
each_key(keycols.size, keys) do |key|
|
||||
Rdb::Fast.search(data, o[:m], keycols, key, first: true).each do |h|
|
||||
puts "#{h.row.from} #{h.row.to} #{h.xfrom} #{h.xto}"
|
||||
if o[:o]
|
||||
|
||||
@@ -217,7 +217,7 @@ STATS.each do |cmd, desc|
|
||||
when 'precision' then nums ? dec.to_s : ''
|
||||
when 'datatype' then filled.empty? || !nums ? '-1' : dec.to_s
|
||||
when 'total' then nums ? fmt(nums.sum, dec) : ''
|
||||
when 'mean' then nums && !nums.empty? ? fmt(nums.sum / nums.size, [dec, 2].max) : ''
|
||||
when 'mean' then nums && !nums.empty? ? fmt(nums.sum / nums.size, (nums.sum % nums.size).zero? ? dec : [dec, 2].max) : ''
|
||||
when 'maximum' then nums && !nums.empty? ? fmt(nums.max, dec) : ''
|
||||
when 'minimum' then nums && !nums.empty? ? fmt(nums.min, dec) : ''
|
||||
end
|
||||
|
||||
+1
-1
@@ -144,7 +144,7 @@ module Rdb
|
||||
dt = Date.jd(s.to_i + JULIAN_OFFSET)
|
||||
case fmt
|
||||
when 'e' then format('%02d/%02d/%02d', dt.day, dt.month, dt.year % 100)
|
||||
when 'u' then format('%02d/%02d/%02d', dt.month, dt.day, dt.year % 100)
|
||||
when 'u' then format('%d/%02d/%02d', dt.month, dt.day, dt.year % 100) # 1/31/89, as in the handbook
|
||||
else format('%02d%02d%02d', dt.year % 100, dt.month, dt.day)
|
||||
end
|
||||
end
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ module Rdb
|
||||
off += l.bytesize
|
||||
end
|
||||
Rdb.die("#{path}: is a list; fast access needs a table") if bytes.start_with?("\n")
|
||||
@head = lines.shift&.line.to_s.split("\t", -1)
|
||||
@head = lines.shift&.line.to_s.split("\t", -1).map(&:strip)
|
||||
lines.shift if lines.first && Table.dash_line?(lines.first.cells)
|
||||
@rows = lines
|
||||
@by_from = lines.to_h { |r| [r.from, r] }
|
||||
|
||||
+2
-1
@@ -22,7 +22,8 @@ module Rdb
|
||||
return parse_list(text) if text.start_with?("\n")
|
||||
|
||||
lines = text.lines.map { |l| l.chomp("\n") }
|
||||
head = (lines.shift || '').split("\t", -1)
|
||||
# justify pads the names too ("Name "); they still name the column
|
||||
head = (lines.shift || '').split("\t", -1).map(&:strip)
|
||||
lines.shift if lines.first && dash_line?(lines.first.split("\t", -1))
|
||||
rows = lines.map { |l| l.split("\t", -1) }
|
||||
new(head, rows.map { |r| r.fill('', r.size...head.size) })
|
||||
|
||||
Reference in New Issue
Block a user