Fehler behoben: Umlaute, Latin-1, Fehlermeldungen, atomares Schreiben
Spaltennamen mit Umlauten in Ausdrücken, Latin-1-Dateien als UTF-8, Fehler als eine Zeile (RDB_DEBUG=1 für Backtrace), Werte mit Tab oder Zeilenumbruch abgelehnt, Tabellen und Indexe über Temp-Datei und rename, update.rdb gibt den Satz bei Editorfehler zurück, sorttable -r stabil.
This commit is contained in:
+29
@@ -46,9 +46,38 @@ module Rdb
|
||||
COMMANDS[name] = Command.new(name, cmd.desc, cmd.syntax.sub(target, name), cmd.block)
|
||||
end
|
||||
|
||||
# Write a file all at once: a temporary file next to it, then rename, so
|
||||
# an interrupted run leaves the old file rather than half a new one.
|
||||
def write_file(path, data)
|
||||
path = File.realpath(path) if File.symlink?(path)
|
||||
tmp = "#{path}.tmp#{Process.pid}"
|
||||
File.binwrite(tmp, data)
|
||||
File.chmod(File.stat(path).mode & 0o7777, tmp) if File.exist?(path)
|
||||
File.rename(tmp, path)
|
||||
ensure
|
||||
File.delete(tmp) if tmp && File.exist?(tmp)
|
||||
end
|
||||
|
||||
# A value is one cell of a tab-separated line: no tab, no line break.
|
||||
def check_cells!(cells)
|
||||
bad = cells.find { |c| c.to_s.match?(/[\t\r\n]/) }
|
||||
die "value #{bad.to_s.inspect} contains a tab or line break" if bad
|
||||
end
|
||||
|
||||
# Errors reach the user as one line; RDB_DEBUG=1 keeps the backtrace.
|
||||
def run(name, args)
|
||||
cmd = COMMANDS[name] or die("unknown command '#{name}'")
|
||||
Env.new(name).instance_exec(args.dup, &cmd.block)
|
||||
rescue Errno::EPIPE
|
||||
exit 0
|
||||
rescue Interrupt
|
||||
exit 130
|
||||
rescue SystemExit
|
||||
raise
|
||||
rescue StandardError => e
|
||||
raise if ENV['RDB_DEBUG'].to_s.match?(/\A(1|yes|true)\z/i)
|
||||
|
||||
die("#{e.message} (#{e.class}; RDB_DEBUG=1 shows where)")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user