RosettaCodeData/Task/Simple-database/Crystal/simple-database.cr
2026-04-30 12:34:36 -04:00

68 lines
1.4 KiB
Crystal

require "json"
DB = "DATABASE"
record Entry, timestamp : Time, description : String, category : String do
include JSON::Serializable
def to_s (io)
timestamp.to_s(io, "%F %T")
io << " - " << description
io << " [" << category << "]" if category != ""
end
end
def load
File.open(DB) do |f|
Array(Entry).from_json f
end
rescue File::NotFoundError
[] of Entry
end
def save (entries)
File.open(DB, "w") do |f|
entries.to_json f
end
end
def usage (errmsg = nil)
puts errmsg if errmsg
print <<-EOU
Usage: #{PROGRAM_NAME} COMMAND ARGS...
Commands:
add DESCRIPTION [CATEGORY] - add entry
last - show last entry
lest - show last in each category
list - show all entries
EOU
exit
end
def check_args (ok)
usage "Invalid number of arguments" unless ok
end
cmd = ARGV.shift? || usage
db = load
if cmd.in?({"help", "h", "-h"})
usage
elsif cmd.in?({"a", "add", "-a"})
check_args 1 <= ARGV.size <= 2
db << Entry.new Time.local, ARGV[0], ARGV[1]? || ""
save db
else
check_args ARGV.size == 0
if cmd == "last"
puts db[-1]?
elsif cmd == "lest"
db.group_by(&.category).to_a.sort_by!(&.[0]).map {|_, es| es.last}.each do |e|
puts e
end
elsif cmd == "list"
db.each do |e| puts e end
else
usage "Invalid command '#{cmd}'"
end
end