Task

Write a simple tool to track a small set of data.

The tool should have a command-line interface to enter at least two different values.

The entered data should be stored in a structured format and saved to disk.

It does not matter what kind of data is being tracked.   It could be a collection (CDs, coins, baseball cards, books), a diary, an electronic organizer (birthdays/anniversaries/phone numbers/addresses), etc.



You should track the following details:

 A description of the item. (e.g., title, name)
 A category or tag (genre, topic, relationship such as “friend” or “family”)
 A date (either the date when the entry was made or some other date that is meaningful, like the birthday); the date may be generated or entered manually
 Other optional fields


The command should support the following Command-line arguments to run:

 Add a new entry
 Print the latest entry
 Print the latest entry for each category
 Print all entries sorted by a date


The category may be realized as a tag or as structure (by making all entries in that category subitems)

The file format on disk should be human readable, but it need not be standardized.   A natively available format that doesn't need an external library is preferred.   Avoid developing your own format if you can use an already existing one.   If there is no existing format available, pick one of:

   JSON
   S-Expressions
   YAML
   others


Related task

   Take notes on the command line 


--
-- demo\rosetta\Simple_db.exw
-- ==========================
--
without js -- (file i/o, gets(0), getenv)
include timedate.e

constant filename = getenv(iff(platform()=WINDOWS?"APPDATA":"HOME"))&"/simple_db.csv"

procedure add(sequence cmd)
    if length(cmd)=0 
    or length(cmd)>2 then
        printf(1,"usage: add name [cat]\n")
    else
        string name = cmd[1],
                cat = iff(length(cmd)=2?cmd[2]:"none")
            datestr = format_timedate(date(),"YYYY/MM/DD h:mmpm")
        integer fn = open(filename,"a")
        printf(fn,"%s,%s,%s\n",{name,cat,datestr})
        close(fn)
    end if
end procedure

procedure last(sequence cmd)
    integer fn = open(filename,"r")
    if fn=-1 then
        puts(1,"file not found\n")
        return
    end if
    integer lc = length(cmd)
    string last = iff(lc?"<no entries for that category>\n":"<empty>\n")
    while 1 do
        object line = gets(fn)
        if atom(line) then exit end if
        if lc=0 or split(line,',')[2]=cmd[1] then
            last = line
        end if
    end while
    puts(1,last)
    close(fn)
end procedure

sequence dates

function by_date(integer d1, integer d2)
    return compare(dates[d1],dates[d2])
end function

procedure sort_by_date()
-- (simple_db.csv should be edited manually to prove the date sort works)
    integer fn = open(filename,"r")
    if fn=-1 then
        puts(1,"file not found\n")
        return
    end if
    sequence lines = {}
    dates = {}
    while 1 do
        object line = gets(fn)
        if atom(line) then exit end if
        lines = append(lines,line)
        dates = append(dates,split(line,',')[3])
    end while
    close(fn)
    sequence tags = custom_sort(by_date,tagset(length(lines)))
    for i=1 to length(tags) do
        puts(1,lines[tags[i]])
    end for
end procedure

procedure process(sequence cmd)
    switch cmd[1] do
        case "add": add(cmd[2..$])
        case "last": last(cmd[2..$])
        case "sort": sort_by_date()
        default: printf(1,"unknown command: %s\n",{cmd[1]})
    end switch
end procedure

constant helptext = """
p demo\rosetta\Simple_db                    -- interactive mode, commands as below
p demo\rosetta\Simple_db add name [cat]     -- add entry
p demo\rosetta\Simple_db last [cat]         -- show last entry [in specified category]
p demo\rosetta\Simple_db sort               -- show full list sorted by date
"""
sequence cl = command_line()
if length(cl)<3 then
    -- interactive mode
    puts(1,helptext)
    while 1 do
        puts(1,">")
        object line = trim(gets(0))
        if atom(line) or length(line)=0 then exit end if
        puts(1,"\n")
        process(split(line))
    end while
else
    process(cl[3..$])
end if
