Simple database: Difference between revisions

Applesoft BASIC
(Applesoft BASIC)
 
(23 intermediate revisions by 11 users not shown)
Line 37:
*   [[Take notes on the command line]]
<br><br>
 
=={{header|11l}}==
{{trans|Kotlin}}
 
<syntaxhighlight lang="11l">T Item
String name, date, category
 
F (name, date, category)
.name = name
.date = date
.category = category
 
F String()
R .name‘, ’(.date)‘, ’(.category)
 
V db_filename = ‘simdb.csv’
 
F load()
[Item] db
L(line) File(:db_filename).read().rtrim("\n").split("\n")
V item = line.split(‘, ’)
db.append(Item(item[0], item[1], item[2]))
R db
 
F store(item)
File(:db_filename, APPEND).write(String(item)"\n")
 
F printUsage()
print(|‘
Usage:
simdb cmd [categoryName]
add add item, followed by optional category
latest print last added item(s), followed by optional category
all print all
For instance: add "some item name" "some category name’)
 
F addItem(args)
I args.len < 2
printUsage()
R
 
V date = Time().strftime(‘%Y-%m-%d %H:%M:%S’)
V cat = I args.len == 3 {args[2]} E ‘none’
store(Item(args[1], date, cat))
 
F printLatest(a)
V db = load()
I db.empty
print(‘No entries in database.’)
R
 
I a.len == 2
L(item) reversed(db)
I item.category == a[1]
print(item)
L.break
L.was_no_break
print(‘There are no items for category '’a[1]‘'’)
E
print(db.last)
 
F printAll()
V db = load()
I db.empty
print(‘No entries in database.’)
R
 
L(item) db
print(item)
 
:start:
I :argv.len C 2..4
S :argv[1].lowercase()
‘add’
addItem(:argv[1..])
‘latest’
printLatest(:argv[1..])
‘all’
printAll()
E
printUsage()
E
printUsage()</syntaxhighlight>
 
{{out}}
The same as in Kotlin.
 
=={{header|BASIC}}==
==={{header|Applesoft BASIC}}===
This program relies on DOS 3.3 to read and write the simple database as a text file on disk. Running the program with no options displays help on how to run the program with the various options.
<syntaxhighlight lang="gwbasic"> 10 FOR I = 0 TO 255:C = PEEK (512 + I):EOL = C = 0 OR C = 141: IF NOT EOL THEN C$ = C$ + CHR$ (C): NEXT I: STOP
20 DOS = (C = 141) * 128:AC = 0: FOR C = I - 1 TO 0 STEP - 1: IF PEEK (512 + C) = ASC (",") + DOS THEN AC = AC + 1: NEXT C
30 D$ = CHR$ (4):M$ = CHR$ (13): READ P$,C$(1),C$(2),C$(3),C$(4):F$ = P$ + ".TXT": ON AC GOTO 100,40,40,40: GOTO 500USAGE
40 C = 0: PRINT D$"OPEN "F$: PRINT D$"READ "F$
50 ONERR GOTO 80
60 INPUT "";NA$,GE$,DA$
70 C = C + 1: GOTO 60
80 POKE 216,0: IF PEEK (222) = 5 THEN PRINT D$"CLOSE "F$: ON AC GOTO 100,200,300,400
90 RESUME
 
REM ADD
100 PRINT M$C$(AC)M$
110 INPUT " NAME: ";NAME$
120 INPUT " GENRE: ";GENRE$
130 INPUT "DATE YYYY-MM-DD: ";DA$
140 PRINT D$"OPEN "F$: PRINT D$"APPEND "F$: PRINT D$"WRITE "F$: PRINT NAME$","GENRE$","DA$: PRINT D$"CLOSE "F$
150 GOTO 600"DONE
 
REM LATEST
200 PRINT M$C$(AC)M$M$" NAME: "NA$M$"GENRE: "GE$M$" DATE: "DA$;
210 GOTO 600"DONE
 
REM LATEST OF EACH GENRE
300 DIM NA$(C),GE$(C),DA$(C):GC = 0: PRINT D$"OPEN "F$: PRINT D$"READ "F$: FOR I = 1 TO C: GOSUB 350:NA$(J) = NA$:GE$(J) = GE$:DA$(J) = DA$: NEXT I: PRINT D$"CLOSE "F$
310 PRINT M$C$(AC)M$: FOR I = 1 TO GC: PRINT M$NA$(I)","GE$(I)","DA$(I);: NEXT I
320 GOTO 600"DONE
350 INPUT "";NA$,GE$,DA$: FOR J = 1 TO GC: IF GE$ = GE$(J) THEN RETURN
360 NEXT J:GC = GC + 1:J = GC: RETURN
 
REM ALL SORTED BY DATE
400 DIM NA$(C),GE$(C),DA$(C),DA(C):DC = 0: PRINT D$"OPEN "F$: PRINT D$"READ "F$: FOR I = 1 TO C: GOSUB 450:NA$(DC) = NA$:GE$(DC) = GE$:DA$(DC) = DA$:DA(DC) = DA(DP):DA(DP) = DC: NEXT I: PRINT D$"CLOSE "F$
410 PRINT M$C$(AC)M$:DA = DA(0): FOR I = 1 TO DC: PRINT M$NA$(DA)","GE$(DA)","DA$(DA);:DA = DA(DA): NEXT I
420 GOTO 600"DONE
450 DP = 0: INPUT "";NA$,GE$,DA$: IF NOT DC THEN DC = 1: RETURN
460 FOR J = 1 TO DC:DA = DA(DP): IF DA$ > DA$(DA) THEN DP = DA:DA = DA(DA): NEXT J:DA = DP
470 DC = DC + 1: RETURN
 
REM USAGE
500 DATA "SIMPLE DATABASE"
510 DATA " RUN: , ADD A NEW ENTRY"
520 DATA " RUN: ,, PRINT THE LATEST ENTRY"
530 DATA " RUN: ,,, LATEST OF EACH GENRE"
540 DATA " RUN: ,,,, ALL SORTED BY DATE"
550 IF NOT DOS THEN C$ = "RUN " + P$
560 PRINT "USAGE:"M$" "C$" ,..."M$" OR";: FOR I = 1 TO 4: PRINT M$C$(I);: NEXT I
 
REM DONE
600 END</syntaxhighlight>
==={{header|Run BASIC}}===
<syntaxhighlight lang="runbasic">sqliteconnect #sql, "f:\client.db" ' Connect to the DB
 
' -------------------------------
' show user options
' -------------------------------
[sho]
cls ' clear screen
button #acd, "Add a new entry", [add]
button #acd, "Print the latest entry", [last]
button #acd, "Print the latest entry for each category", [lastCat]
button #acd, "Print all entries sorted by a date", [date]
button #ex, "Exit", [exit]
wait
 
' ------------------------------------
' add a new entry (user input screen)
' ------------------------------------
[add]
cls ' clear the screen
html "<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 bgcolor=wheat>"
html "<TR align=center BGCOLOR=tan><TD colspan=2>Client Maintenance</TD></TR><TR>"
html "<TD bgcolor=tan align=right>Client Num</TD><TD>"
textbox #clientNum,clientNum$,5
 
html "</TD></TR><TR><TD bgcolor=tan align=right>Name</TD><TD>"
textbox #name,name$,30
 
html "</TD></TR><TR><TD bgcolor=tan align=right>Client Date</TD><TD>"
textbox #clientDate,clientDate$,19
 
html "</TD></TR><TR><TD bgcolor=tan align=right>Category</TD><TD>"
textbox #category,category$,10
 
html "</TD></TR><TR><TR bgcolor=tan><TD colspan=2 ALIGN=CENTER>"
button #acd, "Add", [addIt]
button #ex, "Exit", [sho]
html "</TD></TR></TABLE>"
wait
 
' ---------------------------------------------
' Get data from the screen
' ---------------------------------------------
[addIt]
clientNum = #clientNum contents$()
name$ = trim$(#name contents$())
clientDate$ = trim$(#clientDate contents$())
category$ = trim$(#category contents$())
dbVals$ = clientNum;",'";name$;"','";clientDate$;"','";category$;"'"
sql$ = "INSERT into client VALUES ("; dbVals$ ; ")"
#sql execute(sql$)
goto [sho]
 
' ------------------------------------
' Select last entry
' ------------------------------------
[last]
sql$ = "SELECT *,client.rowid as rowid FROM client ORDER BY rowid desc LIMIT 1"
what$ = "---- Last Entry ----"
goto [shoQuery]
 
' ------------------------------------
' Select by category (Last date only)
' ------------------------------------
[lastCat]
sql$ = "SELECT * FROM client
WHERE client.clientDate = (SELECT max(c.clientDate)
FROM client as c WHERE c.category = client.category)
ORDER BY category"
what$ = "---- Last Category Sequence ----"
goto [shoQuery]
 
' ------------------------------------
' Select by date
' ------------------------------------
[date]
sql$ = "SELECT * FROM client ORDER BY clientDate"
what$ = "---- By Date ----"
 
[shoQuery]
cls
print what$
html "<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0>"
html "<TR align=center bgcolor=wheat><TD>Client<br>Num</TD><TD>Name</TD><TD>Client<br>Date</TD><TD>Category</TD></TR>" ' heading
#sql execute(sql$)
WHILE #sql hasanswer()
#row = #sql #nextrow()
clientNum = #row clientNum()
name$ = #row name$()
clientDate$ = #row clientDate$()
category$ = #row category$()
 
html "<TR><TD align=right>";clientNum;"</TD><TD>";name$;"</TD><TD>";clientDate$;"</TD><TD>";category$;"</TD></TR>"
WEND
html "</TABLE>"
button #c, "Continue", [sho]
wait
 
' ------ the end -------
[exit]
end</syntaxhighlight>
Output:
 
---- User Input ----<br />
<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 bgcolor=wheat>
<TR align=center BGCOLOR=tan><TD colspan=2>Client Maintenance</TD></TR>
<TR><TD bgcolor=tan align=right>Client Num</TD><TD>5</TD></TR>
<TR><TD bgcolor=tan align=right>Name</TD><TD>Dawnridge Winery</TD></TR>
<TR><TD bgcolor=tan align=right>Client Date</TD><TD>2008-06-18 22:16</TD></TR>
<TR><TD bgcolor=tan align=right>Category</TD><TD>wine</TD></TR>
<TR><TR bgcolor=tan><TD colspan=2 ALIGN=CENTER>[Add] [Exit]</TD></TR></TABLE>
 
---- Last Entry ----<br />
<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0>
<TR align=center bgcolor=wheat><TD>Client<br>Num</TD><TD>Name</TD><TD>Client<br>Date</TD><TD>Category</TD></TR>
<TR><TD align=right>5</TD><TD>Dawnridge Winery</TD><TD>2008-06-18 22:16</TD><TD>wine</TD></TR></TABLE>
 
---- Last category Sequence ----<br />
<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0>
<TR align=center bgcolor=wheat><TD>Client<br>Num</TD><TD>Name</TD><TD>Client<br>Date</TD><TD>Category</TD></TR>
<TR><TD align=right>1</TD><TD>Home Sales</TD><TD>2012-01-01 10;20</TD><TD>broker</TD></TR>
<TR><TD align=right>4</TD><TD>Back 40 Equipment</TD><TD>2009-09-18 20:18</TD><TD>farm</TD></TR>
<TR><TD align=right>3</TD><TD>Floral Designs</TD><TD>2010-10-14 09:16</TD><TD>flowers</TD></TR>
<TR><TD align=right>2</TD><TD>Best Foods</TD><TD>2011-02-02 12:33</TD><TD>food</TD></TR>
<TR><TD align=right>5</TD><TD>Dawnridge Winery</TD><TD>2008-06-18 22:16</TD><TD>wine</TD></TR></TABLE>
 
---- Date Sequence ----<br />
<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0>
<TR align=center bgcolor=wheat><TD>Client<br>Num</TD><TD>Name</TD><TD>Client<br>Date</TD><TD>Category</TD></TR>
<TR><TD align=right>5</TD><TD>Dawnridge Winery</TD><TD>2008-06-18 22;16</TD><TD>wine</TD></TR>
<TR><TD align=right>4</TD><TD>Back 40 Equipment</TD><TD>2009-09-18 20:18</TD><TD>farm</TD></TR>
<TR><TD align=right>3</TD><TD>Floral Designs</TD><TD>2010-10-14 09:16</TD><TD>flowers</TD></TR>
<TR><TD align=right>2</TD><TD>Best Foods</TD><TD>2011-02-02 12:33</TD><TD>food</TD></TR>
<TR><TD align=right>1</TD><TD>Home Sales</TD><TD>2012-01-01 10:20</TD><TD>broker</TD></TR></TABLE>
 
=={{header|Bracmat}}==
This is a rather minimal solution. The program is run from the command line of the operating system, in this example the Windows command prompt. The program is stored in a file called 'sdb':
<langsyntaxhighlight lang="bracmat"> whl
' ( arg$:?command
& ( get'db
Line 119 ⟶ 391:
)
);
</syntaxhighlight>
</lang>
First we add some records, a some ships that arrived at the harbour in Rotterdam today.
<pre>bracmat "get$sdb" add name "CORONA BULKER" tag "BULK CARRIER" date "2014.10.21.04:00"
Line 161 ⟶ 433:
* "CRUDE OIL"^(("2014.10.10.02:00"."HS MEDEA")+("2014.10.10.12:00".GHAZAL));</pre>
 
Use is made of Bracmat's automatic normalization of algebraic formula to turn the data into a hierarchical structure, with the tag as the top level and the date/time immediately below that level.
 
=={{header|C}}==
Line 172 ⟶ 444:
"Treasure Beach","Argus","Jemky","09-22-1999","Lancast"
 
<langsyntaxhighlight Clang="c">#include <stdio.h>
#include <stdlib.h> /* malloc */
#include <string.h> /* strlen */
Line 364 ⟶ 636:
}
else return ((*p1)->date > (*p2)->date);
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight Clang="c sharp">
using System;
using System.IO;
Line 691 ⟶ 963:
}
}
</syntaxhighlight>
</lang>
{{out| Program Input and Output}}
<pre>
Line 729 ⟶ 1,001:
This is a souped-up version of the task from [[Take notes on the command line]]. It stores the current date, a tag, a title and a note as an entry in a file. The database produced is not particularly human-readable or easy to modify, but it is in a well-structured format.
{{works with|OpenCOBOL}}
<langsyntaxhighlight lang="cobol"> IDENTIFICATION DIVISION.
PROGRAM-ID. simple-database.
 
Line 990 ⟶ 1,262:
"The title should be specified as shown for -c."
DISPLAY " -t - Show all the entries sorted by tag."
.</langsyntaxhighlight>
 
Sample session:
Line 1,029 ⟶ 1,301:
Tested with [[Common Lisp]]. ''(Save the code below as db.lisp)''
 
<langsyntaxhighlight lang="lisp">(defvar *db* nil)
 
(defvar *db-cat* (make-hash-table :test 'equal))
Line 1,146 ⟶ 1,418:
nil))
 
(db-cmd-run (db-argv))</langsyntaxhighlight>
 
 
Line 1,196 ⟶ 1,468:
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.string, std.conv, std.array,
std.file, std.csv, std.datetime;
 
Line 1,282 ⟶ 1,554:
default: printUsage(); break;
}
}</langsyntaxhighlight>
{{out}}
<pre>C:\>simdb add item1 cat1
Line 1,331 ⟶ 1,603:
item6,2014-06-04T16:01:55,cat4
item7,2014-06-04T16:02:01,cat4</pre>
 
=={{header|Emacs Lisp}}==
<syntaxhighlight lang="lisp">
(defun dbe-next-id ()
(unless (boundp '**dbe-current-id**) (setq **dbe-current-id** 1))
(let ((id **dbe-current-id**))
(cl-incf **dbe-current-id**)
id ) )
 
(defun dbe-rows (fn-handle-row &rest params)
(let ((has-more 't) current-line linum1 linum2
(fn-continue (plist-get params :continue)))
(save-window-excursion
(switch-to-buffer "**content**")
(beginning-of-buffer)
(if fn-continue (setq has-more (funcall fn-continue)))
(while has-more
(setq current-line
(buffer-substring (line-beginning-position)
(line-end-position)))
(unless (string= current-line "")
(funcall fn-handle-row (read current-line)))
(if fn-continue (setq has-more (funcall fn-continue)))
(setq linum1 (line-number-at-pos (point)))
(forward-line)
(setq linum2 (line-number-at-pos (point)))
(if (= linum1 linum2) (setq has-more nil))
)
)
)
)
(defun dbe-insert (row)
(interactive "xPlease enter the row data in plist format: ")
(save-window-excursion
(switch-to-buffer "**content**")
(end-of-buffer)
(let (row-data)
(setq row-data (append (list 'id (dbe-next-id)) (ensure-list row)))
(insert (format "%s\n" row-data))
(message ">> Row added: %s" row-data) ) ) )
 
(defun dbe-find-by-id (row-id)
(interactive "nPlease enter row id: ")
(let (row-found)
(dbe-rows (lambda (row)
(when (equal (plist-get row 'id) row-id)
(setq row-found row)) )
:continue (lambda () (null row-found)))
(message ">> Row found: %s" row-found)
)
)
</syntaxhighlight>
 
{{out}}
 
<pre>
M-x dbe-insert
Please enter the row data in plist format: (name "book1" author "author1")
>> Row added: (id 1 name book1 author author1)
 
M-x dbe-insert
Please enter the row data in plist format: (name "book2" author "author2")
>> Row added: (id 2 name book2 author author2)
 
M-x dbe-find-by-id
Please enter row id: 2
>> Row found: (id 2 name book2 author author2)
</pre>
 
=={{header|Erlang}}==
<syntaxhighlight lang="erlang">
<lang Erlang>
#! /usr/bin/env escript
 
Line 1,388 ⟶ 1,730:
io:fwrite( "Data stored in ~p~n", [file()] ),
init:stop().
</syntaxhighlight>
</lang>
Command line session started with these file contents as database:
<pre>
Line 1,409 ⟶ 1,751:
2013-9-16 comic gustaf
</pre>
 
 
=={{header|Forth}}==
Line 1,488 ⟶ 1,829:
 
Code:
<langsyntaxhighlight lang="forth">\ sdb.fs Simple database. Gforth 0.7.0 specific
' noop is bootmessage
 
Line 1,616 ⟶ 1,957:
cr cr ;
current !
SEAL godb</langsyntaxhighlight>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,958 ⟶ 2,299:
fmt.Println(err)
}
}</langsyntaxhighlight>
 
=={{header|Haskell}}==
 
Line 1,965 ⟶ 2,307:
Item {description = "La traviata", category = ["Classical"], date = Date 2012 10 19, optional = ["Giuseppe Verdi","1853"]}
 
<langsyntaxhighlight Haskelllang="haskell">import Control.Monad.State
import Data.List (sortBy, nub)
import System.Environment (getArgs, getProgName)
Line 2,093 ⟶ 2,435:
mapM_ (hPutStrLn hw . show) v
hClose hw
</syntaxhighlight>
</lang>
 
=={{header|J}}==
Line 2,099 ⟶ 2,441:
J comes with a sql database, jdb. Jdb's columns are memory mapped files with header information. These won't meet the human readable data file requirement. Hence, this program:
 
<langsyntaxhighlight lang="j">HELP=: 0 :0
Commands:
 
Line 2,207 ⟶ 2,549:
 
exit 0
</syntaxhighlight>
</lang>
Assume the j code is stored in file s . These bash commands, stored in file input , create a database using add .
<langsyntaxhighlight lang="sh">D='jconsole s dataflow'
$D add name expression algebraic rank valence example explanation
Line 2,222 ⟶ 2,564:
$D add atop 'x f@g y' 'f(g(x,y))' 'rank of g' dyad '>@{.' '(lisp) open the car'
$D add 'many more!'
</syntaxhighlight>
</lang>
Now we look up data from the bash command line.
<syntaxhighlight lang="sh">
<lang sh>
$ . input # source the input
$ echo $D
Line 2,300 ⟶ 2,642:
'2012-02-08:23:45:06.515';'atop';'x f@g y';'f(g(x,y))';'rank of g';'dyad';'>@{.';'(lisp) open the car'
'2012-02-08:23:45:06.539';'many more!'
$ </langsyntaxhighlight>
 
=={{header|Java}}==
{{trans|D}}
{{works with|Java|7}}
<langsyntaxhighlight lang="java">import java.io.*;
import java.text.*;
import java.util.*;
Line 2,429 ⟶ 2,771:
+ "\"some category name\"");
}
}</langsyntaxhighlight>
 
Output:
Line 2,465 ⟶ 2,807:
item5,2014-06-03 19:30:23,cat3</pre>
 
=={{header|Julia}}==
Command line CSV based simple database. The file used contained:<pre>
Name,Birthdate,State,Relation,Email
Sally Whittaker,1988-12-05,Illinois,friend,sally@mail.com
Belinda Jameson,1994-02-17,California,family,beljames@example.com
Jeff Bragg,2018-10-10,Texas,family,jb@texas.edu
Sandy Allen,2002-03-09,Colorado,friend,sandya@mail.com
Fred Kobo,1967-10-10,Colorado,friend,fkobo@example.net</pre>
<syntaxhighlight lang="julia">using CSV, DataFrames, ArgParse, Dates
 
setting = ArgParseSettings()
@add_arg_table setting begin
"--add"
help = "add an entry, within double quotes, comma separated as \"name,birthdate,state,relation,email\" with birthdate as yyyy-mm-dd"
"--latest"
action = :store_true
nargs = 0
help = "print latest (last) entry"
"--latestfriend"
action = :store_true
nargs = 0
help = "print last friend listed"
"--latestfamily"
action = :store_true
nargs = 0
help = "print last family member listed"
"--listbyage"
action = :store_true
nargs = 0
help = "print all ages and entries in birth order"
end
 
const filename = "example.csv"
const df = CSV.File(filename, dateformat="yyyy-mm-dd") |> DataFrame
const commands = parse_args(setting)
if length(ARGS) == 0
ArgParse.show_help(setting)
end
const changeflag = [false]
 
for (k, v) in commands
if k == "add" && v != nothing
newrow = Vector{Any}(split(v, r","))
if length(newrow) == 5 && tryparse(DateTime, newrow[2]) != nothing
newrow[2] = DateTime(newrow[2])
push!(df, newrow)
changeflag[1] = true
println("Added entry $newrow.")
end
elseif k == "latest" && v
println("The latest entry is $(df[end, :])")
elseif k == "latestfriend" && v
println(df[df.Relation .== "friend", :][end, :])
elseif k == "latestfamily" && v
println(df[df.Relation .== "family", :][end, :])
elseif k == "listbyage" && v
dobcol = df[:Birthdate]
age = map(x -> round((now() - DateTime(x)).value /(1000*3600*24*365.25), digits=1), dobcol)
df2 = deepcopy(df)
df2 = insert!(df, 1, age, :Age)
println(sort(df2, (:Age)))
end
end
 
if changeflag[1]
CSV.write(filename, df)
println("Changes written to file $filename.")
end
</syntaxhighlight>
 
=={{header|Kotlin}}==
{{trans|Java}}
... though not quite the same.
<langsyntaxhighlight lang="scala">// version 1.2.31
 
import java.text.SimpleDateFormat
Line 2,578 ⟶ 2,989:
else -> printUsage()
}
}</langsyntaxhighlight>
 
{{out}}
Line 2,601 ⟶ 3,012:
item5, 2018-03-23 16:49:46, cat3
</pre>
 
=={{header|M2000 Interpreter}}==
Write the code on a UTF-8 text file as tool.gsb
 
Assign gsb files to open with M2000.exe (the M2000 environment)
 
Open the folder where exist tool.gsb in a cmd window
 
then follow the > lines in the out session
 
The format of file is xml, Utf8 with a BOM.
 
The M2000 environment not used here, all the output redirect to console. (Although the environment is a Window program, we can attach the console).
 
 
<syntaxhighlight lang="m2000 interpreter">
MODULE GLOBAL interpret {
global filename$="base1.xml"
module latest {
PrintConsoleLn("The latest entry is:")
if exist(filename$) else exit
declare xml xmlData
with xml, "xml" as doc$, "beautify" as beautify
doc$=string$(eval$(buffer(filename$)) as UTF8dec)
with xml, "lastchild" set child
with child,"attr" as attr$()
PrintConsoleLn(attr$("name")+","+@tag$()+","+attr$("date"))
declare xml nothing
}
module latestForEachTag {
PrintConsoleLn("latest entry for each tag:")
if exist(filename$) else exit
declare xml xmlData
with xml, "xml" as doc$, "beautify" as beautify
doc$=string$(eval$(buffer("base1.xml")) as UTF8dec)
with xml, "firstchild" as firstchild
child=firstchild
with child,"attr" as attr$()
inventory alfa
do
if not exist(alfa, @tag$()) then
append alfa, @tag$():=child
else
return alfa, @tag$():=child
end if
Method xml, "EndOffChilds", &child as ok
when ok
sort alfa
k=each(alfa)
while k
child=eval(k)
PrintConsoleLn(attr$("name")+","+@tag$()+","+attr$("date"))
end while
declare xml nothing
}
module All {
PrintConsoleLn("All entries sorted by date:")
if exist(filename$) else exit
declare xml xmlData
with xml, "xml" as doc$, "beautify" as beautify
doc$=string$(eval$(buffer("base1.xml")) as UTF8dec)
with xml, "firstchild" as firstchild
child=firstchild
with child,"attr" as attr$()
inventory alfa
i=0
do
// prevent same keys using a unique patch key
append alfa, attr$("date")+str$(i,"000000"):=child
i++
Method xml, "EndOffChilds", &child as ok
when ok
sort alfa
k=each(alfa)
while k
child=eval(k)
PrintConsoleLn(attr$("name")+","+@tag$()+","+attr$("date"))
end while
declare xml nothing
}
module add (line$) {
line$=trim$(line$)
if line$="" then exit
declare xml xmlData
with xml, "xml" as doc$, "beautify" as beautify
bom$=str$(format$("\uef\ubb\ubf"))
// len(bom$)=1.5 (1.5*2=3 bytes)
k=0
if exist(filename$) then try {k=filelen(filename$)}
if k<10 then
method xml, "PrepareNodeSimple", "xml" as ProcessInstructions
method xml, "PlaceAttributeToNode", ProcessInstructions, "version", "1.0"
method xml, "PlaceAttributeToNode", ProcessInstructions, "encoding", "utf-8-sig"
method xml, "PlaceProcessingInstructions", ProcessInstructions
method xml, "PrepareNode", "MyFile" as Node
method xml, "InsertNode", Node
else
doc$=string$(eval$(buffer(filename$)) as UTF8dec)
end if
a$=""""+line$
def name$, tag$,date$
do
a$=rightpart$(a$, """") : what$=lcase$(trim$(leftpart$(a$, """")))
if what$="" then exit
a$=rightpart$(a$, """") :par$=leftpart$(a$, """")
select case what$
case "name"
name$=par$
case "tag"
tag$=par$
case "date"
date$=par$
end select
always
if name$<>"" and date$<>"" then
method xml, "PrepareNode", "Row", "" as Node1
method xml, "PlaceAttributeToNode", Node1, "name", name$
if tag$<>"" then method xml, "PlaceAttributeToNode", Node1, "tag", tag$
method xml, "PlaceAttributeToNode", Node1, "date", date$
method xml, "AppendChild", Node1
open filename$ for wide output as #f
print #f, bom$;string$(doc$ as UTF8enc);
close #f
beautify=-4
PrintConsoleLn(doc$)
end if
declare xml nothing
}
declare FreeConsole lib "Kernel32.FreeConsole"
declare GetStdHandle lib "Kernel32.GetStdHandle" {long a}
declare AttachConsole lib "Kernel32.AttachConsole" {long a}
declare CloseHandle lib "Kernel32.CloseHandle" {long a}
declare global WriteCons Lib "Kernel32.WriteConsoleW" {long cons, a$, long n, Long p, long u}
long STD_OUTPUT_HANDLE=-11
global retvalue
buffer clear retvalue as long
ret=AttachConsole(-1)
global m=GetStdHandle(STD_OUTPUT_HANDLE)
if ret=0 then beep: exit
if not islet then
try {
open "tool.bat" for output as #f
print #f, {@}+appdir$+{m2000.exe data {%*}: dir %cd%:load tool
}
close #f
}
PrintConsoleLn("")
dos "tool.bat"
else
read cmd$
cmd$=trim$(cmd$)+" "
select case lcase$(leftpart$(cmd$, " "))
case "add"
add rightpart$(cmd$," ")
case "latest"
latest
case "latest-per-tag"
latestForEachTag
case "all-entries"
all
case else
help()
end select
end if
call void closehandle(m)
call void freeconsole()
 
Sub PrintConsole(a$)
Call Void WriteCons(m, a$, Len(a$), retvalue(0), 0)
End Sub
Sub PrintConsoleLn(a$)
a$+={
}
Call Void WriteCons(m, a$, Len(a$), retvalue(0), 0)
End Sub
// function is static here but can be called from child modules, because there are in the same block of code
// although attr$() must defined in each module. (scope constrain to module block, for local identifiers).
function tag$()
try { // if no tag exist error raised
=attr$("tag")
}
end function
Sub Help()
h$={Commands:
tool add name "anyname" tag "tagtext" date "YYYY.MM.DD.HH:MM"
tool latest
tool latest-per-tag
tool all-entries
}
PrintConsole(h$)
End Sub
}
module interpret1 {
try {interpret}
}
interpret1: end
</syntaxhighlight>
{{out}}
<pre>
first time the program make a tool.bat
>tool.gsb
 
So now we can call the tool bat.
>tool
Commands:
tool add name "anyname" tag "tagtext" date "YYYY.MM.DD.HH:MM"
tool latest
tool latest-per-tag
tool all-entries
 
>tool add name "BOB" tag "EAT A LOT" date "2022.10.21.04:00"
>tool add name "JOHN" tag "DRINK WATER" "date 2022.10.15.12:00"
>tool add name "PAUL" tag "EAT A LOT" date "2022.10.13.22:00"
>tool add name "SUZAN" tag "DRINK WATER" date "2022.10.13.12:00"
>tool add name "PHILIP" tag "DRINK WATER" date "2022.10.13.10:00"
>tool add name "MONDY" tag "EAT A LOT" date "2022.10.10.12:00"
>tool add name "MARY" tag "PIZZA FRIENDLY" date "2022.10.10.12:00"
>tool add name "DONALD" tag "PIZZA FRIENDLY" date "2022.10.10.02:00"
>tool add name "GEORGE" date "2022.11.29.16:55"
 
This is the last print from last tool add:
<?xml version="1.0" encoding="utf-8-sig"?>
<MyFile>
<Row name="BOB" tag="EAT A LOT" date="2022.10.21.04:00"></Row>
<Row name="PAUL" tag="EAT A LOT" date="2022.10.13.22:00"></Row>
<Row name="SUZAN" tag="DRINK WATER" date="2022.10.13.12:00"></Row>
<Row name="PHILIP" tag="DRINK WATER" date="2022.10.13.10:00"></Row>
<Row name="MONDY" tag="EAT A LOT" date="2022.10.10.12:00"></Row>
<Row name="MARY" tag="PIZZA FRIENDLY" date="2022.10.10.12:00"></Row>
<Row name="DONALD" tag="PIZZA FRIENDLY" date="2022.10.10.02:00"></Row>
<Row name="GEORGE" date="2022.11.29.16:55"></Row>
</MyFile>
 
 
>tool latest
The latest entry is:
GEORGE,,2022.11.29.16:55
 
>tool latest-per-tag
latest entry for each tag:
GEORGE,,2022.11.29.16:55
PHILIP,DRINK WATER,2022.10.13.10:00
MONDY,EAT A LOT,2022.10.10.12:00
DONALD,PIZZA FRIENDLY,2022.10.10.02:00
 
>tool all-entries
All entries sorted by date:
DONALD,PIZZA FRIENDLY,2022.10.10.02:00
MONDY,EAT A LOT,2022.10.10.12:00
MARY,PIZZA FRIENDLY,2022.10.10.12:00
PHILIP,DRINK WATER,2022.10.13.10:00
SUZAN,DRINK WATER,2022.10.13.12:00
PAUL,EAT A LOT,2022.10.13.22:00
BOB,EAT A LOT,2022.10.21.04:00
GEORGE,,2022.11.29.16:55
</pre>
 
=={{header|Nim}}==
{{trans|D}}
{{trans|Kotlin}}
There are some important differences with D version and Kotlin versions. Firstly, the way to manage the command arguments is somewhat different. And secondly, the database is stored in JSON format rather than in CSV format. Indeed, if Nim provides a parser of CSV files, it provides better support for JSON with procedures for serialization of Nim objects to JSON and deserialization from JSON to Nim objects. This can be seen in the following program.
 
<syntaxhighlight lang="nim">import algorithm, json, os, strformat, strutils, times
 
const FileName = "simdb.json"
 
type
 
Item = object
name: string
date: string
category: string
 
Database = seq[Item]
 
DbError = object of CatchableError
 
 
proc load(): Database =
if fileExists(FileName):
let node = try: FileName.parseFile()
except JsonParsingError:
raise newException(DbError, getCurrentExceptionMsg())
result = node.to(DataBase)
 
 
proc store(db: Database) =
try:
FileName.writeFile $(%* db)
except IOError:
quit "Unable to save database.", QuitFailure
 
 
proc addItem(args: seq[string]) =
var db = try: load()
except DbError: quit getCurrentExceptionMsg(), QuitFailure
 
let date = now().format("yyyy-MM-dd HH:mm:ss")
let cat = if args.len == 2: args[1] else: "none"
db.add Item(name: args[0], date: date, category: cat)
db.store()
 
 
proc printLatest(args: seq[string]) =
let db = try: load()
except DbError: quit getCurrentExceptionMsg(), QuitFailure
if db.len == 0:
echo "No entries in database."
return
 
# No need to sort db as items are added chronologically.
if args.len == 1:
var found = false
for item in reversed(db):
if item.category == args[0]:
echo item
found = true
break
if not found:
echo &"There are no items for category '{args[0]}'"
else:
echo db[^1]
 
 
proc printAll() =
let db = try: load()
except DbError: quit getCurrentExceptionMsg(), QuitFailure
if db.len == 0:
echo "No entries in database."
return
for item in db:
echo item
 
 
proc printUsage() =
echo &"""
Usage:
{getAppFilename().splitPath().tail} cmd [categoryName]
 
add add item, followed by optional category
latest print last added item(s), followed by optional category
all print all
 
For instance: add "some item name" "some category name"
"""
quit QuitFailure
 
 
if paramCount() notin 1..3: printUsage()
 
var params = commandLineParams()
let command = params[0].toLowerAscii
params.delete(0)
case command
of "add":
if params.len == 0: printUsage()
addItem(params)
of "latest":
if params.len > 1: printUsage()
printLatest(params)
of "all":
if params.len != 0: printUsage()
printAll()</syntaxhighlight>
 
{{out}}
Sample session (same as that of Kotlin).
<pre>$ ./simple_database add item1
$ ./simple_database add item2
$ ./simple_database add item3 cat3
$ ./simple_database add item4 cat3
$ ./simple_database add item5 cat3
$ ./simple_database latest
(name: "item5", date: "2021-04-09 00:31:34", category: "cat3")
$ ./simple_database latest none
(name: "item2", date: "2021-04-09 00:31:08", category: "none")
$ ./simple_database latest cat4
There are no items for category 'cat4'
$ ./simple_database all
(name: "item1", date: "2021-04-09 00:31:03", category: "none")
(name: "item2", date: "2021-04-09 00:31:08", category: "none")
(name: "item3", date: "2021-04-09 00:31:19", category: "cat3")
(name: "item4", date: "2021-04-09 00:31:25", category: "cat3")
(name: "item5", date: "2021-04-09 00:31:34", category: "cat3")</pre>
 
=={{header|Perl}}==
<langsyntaxhighlight Perllang="perl">#!/usr/bin/perl
use warnings;
use strict;
Line 2,720 ⟶ 3,515:
if $by_date;
}
}</langsyntaxhighlight>
Sample session<pre> ~ $ db.pl n 'Donald Trump' Republican 2017-01-20
~ $ db.pl n 'Barack Obama' Democratic 2009-01-20
Line 2,739 ⟶ 3,534:
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(notonline)-->
<lang Phix>--
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\Simple_db.exw
-- demo\rosetta\Simple_db.exw
-- ==========================
-- ==========================
--
--</span>
include timedate.e
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (file i/o, gets(0), getenv)</span>
 
<span style="color: #008080;">include</span> <span style="color: #004080;">timedate</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
constant filename = getenv(iff(platform()=WINDOWS?"APPDATA":"HOME"))&"/simple_db.csv"
 
<span style="color: #008080;">constant</span> <span style="color: #000000;">filename</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getenv</span><span style="color: #0000FF;">(</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">WINDOWS</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"APPDATA"</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"HOME"</span><span style="color: #0000FF;">))&</span><span style="color: #008000;">"/simple_db.csv"</span>
procedure add(sequence cmd)
if length(cmd)=0
<span style="color: #008080;">procedure</span> <span style="color: #000000;">add</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">cmd</span><span style="color: #0000FF;">)</span>
or length(cmd)>2 then
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cmd</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span>
printf(1,"usage: add name [cat]\n")
<span style="color: #008080;">or</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cmd</span><span style="color: #0000FF;">)></span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span>
else
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"usage: add name [cat]\n"</span><span style="color: #0000FF;">)</span>
string name = cmd[1]
<span style="color: #008080;">else</span>
string cat = iff(length(cmd)=2?cmd[2]:"none")
<span style="color: #004080;">string</span> <span style="color: #000000;">name</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">cmd</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span>
string datestr = format_timedate(date(),"YYYY/MM/DD h:mmpm")
<span style="color: #000000;">cat</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cmd</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">2</span><span style="color: #0000FF;">?</span><span style="color: #000000;">cmd</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]:</span><span style="color: #008000;">"none"</span><span style="color: #0000FF;">)</span>
integer fn = open(filename,"a")
<span style="color: #000000;">datestr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">format_timedate</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">date</span><span style="color: #0000FF;">(),</span><span style="color: #008000;">"YYYY/MM/DD h:mmpm"</span><span style="color: #0000FF;">)</span>
printf(fn,"%s,%s,%s\n",{name,cat,datestr})
<span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #000000;">filename</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"a"</span><span style="color: #0000FF;">)</span>
close(fn)
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s,%s,%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">name</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cat</span><span style="color: #0000FF;">,</span><span style="color: #000000;">datestr</span><span style="color: #0000FF;">})</span>
end if
<span style="color: #7060A8;">close</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
procedure last(sequence cmd)
integer fn = open(filename,"r")
<span style="color: #008080;">procedure</span> <span style="color: #000000;">last</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">cmd</span><span style="color: #0000FF;">)</span>
if fn=-1 then
<span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #000000;">filename</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"r"</span><span style="color: #0000FF;">)</span>
puts(1,"file not found\n")
<span style="color: #008080;">if</span> <span style="color: #000000;">fn</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
return
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"file not found\n"</span><span style="color: #0000FF;">)</span>
end if
<span style="color: #008080;">return</span>
integer lc = length(cmd)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
string last = iff(lc?"<no entries for that category>\n":"<empty>\n")
<span style="color: #004080;">integer</span> <span style="color: #000000;">lc</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cmd</span><span style="color: #0000FF;">)</span>
while 1 do
<span style="color: #004080;">string</span> <span style="color: #000000;">last</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lc</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"&lt;no entries for that category&gt;\n"</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"&lt;empty&gt;\n"</span><span style="color: #0000FF;">)</span>
object line = gets(fn)
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
if atom(line) then exit end if
<span style="color: #004080;">object</span> <span style="color: #000000;">line</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">gets</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
if lc=0 or split(line,',')[2]=cmd[1] then
<span style="color: #008080;">if</span> <span style="color: #004080;">atom</span><span style="color: #0000FF;">(</span><span style="color: #000000;">line</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
last = line
<span style="color: #008080;">if</span> <span style="color: #000000;">lc</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">or</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">line</span><span style="color: #0000FF;">,</span><span style="color: #008000;">','</span><span style="color: #0000FF;">)[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">cmd</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">last</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">line</span>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
puts(1,last)
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
close(fn)
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">last</span><span style="color: #0000FF;">)</span>
end procedure
<span style="color: #7060A8;">close</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
sequence dates
 
<span style="color: #004080;">sequence</span> <span style="color: #000000;">dates</span>
function by_date(integer d1, integer d2)
return compare(dates[d1],dates[d2])
<span style="color: #008080;">function</span> <span style="color: #000000;">by_date</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">d1</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">d2</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #008080;">return</span> <span style="color: #7060A8;">compare</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dates</span><span style="color: #0000FF;">[</span><span style="color: #000000;">d1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">dates</span><span style="color: #0000FF;">[</span><span style="color: #000000;">d2</span><span style="color: #0000FF;">])</span>
constant r_by_date = routine_id("by_date")
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
procedure sort_by_date()
<span style="color: #008080;">procedure</span> <span style="color: #000000;">sort_by_date</span><span style="color: #0000FF;">()</span>
-- (simple_db.csv should be edited manually to prove the date sort works)
<span style="color: #000080;font-style:italic;">-- (simple_db.csv should be edited manually to prove the date sort works)</span>
integer fn = open(filename,"r")
<span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #000000;">filename</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"r"</span><span style="color: #0000FF;">)</span>
if fn=-1 then
<span style="color: #008080;">if</span> <span style="color: #000000;">fn</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
puts(1,"file not found\n")
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"file not found\n"</span><span style="color: #0000FF;">)</span>
return
<span style="color: #008080;">return</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
sequence lines = {}
<span style="color: #004080;">sequence</span> <span style="color: #000000;">lines</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
dates = {}
<span style="color: #000000;">dates</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
while 1 do
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
object line = gets(fn)
<span style="color: #004080;">object</span> <span style="color: #000000;">line</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">gets</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
if atom(line) then exit end if
<span style="color: #008080;">if</span> <span style="color: #004080;">atom</span><span style="color: #0000FF;">(</span><span style="color: #000000;">line</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
lines = append(lines,line)
<span style="color: #000000;">lines</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">,</span><span style="color: #000000;">line</span><span style="color: #0000FF;">)</span>
dates = append(dates,split(line,',')[3])
<span style="color: #000000;">dates</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dates</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">line</span><span style="color: #0000FF;">,</span><span style="color: #008000;">','</span><span style="color: #0000FF;">)[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">])</span>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
close(fn)
<span style="color: #7060A8;">close</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
sequence tags = custom_sort(r_by_date,tagset(length(lines)))
<span style="color: #004080;">sequence</span> <span style="color: #000000;">tags</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">custom_sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">by_date</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">)))</span>
for i=1 to length(tags) do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tags</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
puts(1,lines[tags[i]])
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">tags</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]])</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
 
procedure process(sequence cmd)
<span style="color: #008080;">procedure</span> <span style="color: #000000;">process</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">cmd</span><span style="color: #0000FF;">)</span>
switch cmd[1] do
<span style="color: #008080;">switch</span> <span style="color: #000000;">cmd</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">do</span>
case "add": add(cmd[2..$])
<span style="color: #008080;">case</span> <span style="color: #008000;">"add"</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cmd</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$])</span>
case "last": last(cmd[2..$])
<span style="color: #008080;">case</span> <span style="color: #008000;">"last"</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">last</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cmd</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$])</span>
case "sort": sort_by_date()
<span style="color: #008080;">case</span> <span style="color: #008000;">"sort"</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">sort_by_date</span><span style="color: #0000FF;">()</span>
default: printf(1,"unknown command: %s\n",{cmd[1]})
<span style="color: #008080;">default</span><span style="color: #0000FF;">:</span> <span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"unknown command: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">cmd</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]})</span>
end switch
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
 
constant helptext = """
<span style="color: #008080;">constant</span> <span style="color: #000000;">helptext</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
p demo\rosetta\Simple_db -- interactive mode, commands as below
p demo\rosetta\Simple_db add name [cat] -- addinteractive mode, commands as entrybelow
p demo\rosetta\Simple_db lastadd name [cat] -- show lastadd entry [in specified category]
p demo\rosetta\Simple_db sort last [cat] -- show fulllast listentry sorted[in byspecified datecategory]
p demo\rosetta\Simple_db sort -- show full list sorted by date
"""
"""</span>
sequence cl = command_line()
<span style="color: #004080;">sequence</span> <span style="color: #000000;">cl</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">command_line</span><span style="color: #0000FF;">()</span>
if length(cl)<3 then
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cl</span><span style="color: #0000FF;">)<</span><span style="color: #000000;">3</span> <span style="color: #008080;">then</span>
-- interactive mode
<span style="color: #000080;font-style:italic;">-- interactive mode</span>
puts(1,helptext)
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">helptext</span><span style="color: #0000FF;">)</span>
while 1 do
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
puts(1,">")
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"&gt;"</span><span style="color: #0000FF;">)</span>
object line = trim(gets(0))
<span style="color: #004080;">object</span> <span style="color: #000000;">line</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">gets</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">))</span>
if atom(line) or length(line)=0 then exit end if
<span style="color: #008080;">if</span> <span style="color: #004080;">atom</span><span style="color: #0000FF;">(</span><span style="color: #000000;">line</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">or</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">line</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
puts(1,"\n")
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
process(split(line))
<span style="color: #000000;">process</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">line</span><span style="color: #0000FF;">))</span>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
else
<span style="color: #008080;">else</span>
process(cl[3..$])
<span style="color: #000000;">process</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cl</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">..$])</span>
end if</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<!--</syntaxhighlight>-->
Sample session
<pre>
Line 2,868 ⟶ 3,665:
=={{header|PicoLisp}}==
The '[http://software-lab.de/doc/refR.html#rc rc]' resource file handling function is used typically for such tasks. It also takes care of proper locking and protection.
<langsyntaxhighlight PicoLisplang="picolisp">#!/usr/bin/pil
 
(de usage ()
Line 2,903 ⟶ 3,700:
(T (usage)) ) )
 
(bye)</langsyntaxhighlight>
Test:
<pre>$ sdb CDs add "Title 1" "Category 1" 2011-11-13
Line 2,928 ⟶ 3,725:
=={{header|Pike}}==
{{trans|Common Lisp}} (simplified)
<langsyntaxhighlight Pikelang="pike">mapping db = ([]);
 
mapping make_episode(string series, string title, string episode, array date)
Line 3,081 ⟶ 3,878:
else
watch_list(db);
}</langsyntaxhighlight>
 
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
<lang PowerShell>
function db
{
Line 3,166 ⟶ 3,963:
db -Name Vince -Category family -Birthday 3/10/1960
db -Name Wayne -Category coworker -Birthday 5/29/1962
</syntaxhighlight>
</lang>
Here is the data from the CSV file as a PowerShell Object:
<syntaxhighlight lang="powershell">
<lang PowerShell>
db
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 3,183 ⟶ 3,980:
</pre>
The latest entry:
<syntaxhighlight lang="powershell">
<lang PowerShell>
db -Latest
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 3,193 ⟶ 3,990:
</pre>
The latest entries by category:
<syntaxhighlight lang="powershell">
<lang PowerShell>
db -LatestByCategory
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 3,205 ⟶ 4,002:
</pre>
The database sorted on the Birthday property:
<syntaxhighlight lang="powershell">
<lang PowerShell>
db -SortedByDate
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 3,221 ⟶ 4,018:
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">#!/usr/bin/python3
 
'''\
Line 3,328 ⟶ 4,125:
now = datetime.datetime.utcnow()
args._date = now.isoformat()
do_command[args.command](args, dbname)</langsyntaxhighlight>
 
;Sample session (Unix):
Line 3,376 ⟶ 4,173:
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#!/usr/bin/env racket
#lang racket
Line 3,403 ⟶ 4,200:
(for-each (compose1 show last/cat) (remove-duplicates (map cadr data)))]
[else (error 'sdb "bad printout mode")])])
</syntaxhighlight>
</lang>
 
Sample run:
Line 3,438 ⟶ 4,235:
[cds] Some-CD; 2013-01-03
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
A generic client/server JSON database.<br>
<b>server.raku:</b>
<syntaxhighlight lang="raku" line>#!/usr/bin/env raku
use JSON::Fast ;
sub MAIN( :$server='0.0.0.0', :$port=3333, :$dbfile='db' ) {
my %db;
my %index;
my $dbdata = slurp "$dbfile.json" ;
my $indexdata = slurp "{$dbfile}_index.json" ;
%db = from-json($dbdata) if $dbdata ;
%index = from-json($indexdata) if $indexdata ;
react {
whenever IO::Socket::Async.listen( $server , $port ) -> $conn {
whenever $conn.Supply.lines -> $line {
my %response = 'status' => '' ;
my $msg = from-json $line ;
say $msg.perl ;
given $msg<function> {
when 'set' {
%db{ $msg<topic> } = $msg<message> ;
%response<status> = 'ok' ;
%index<last_> = $msg<topic> ;
for %index<keys_>.keys -> $key {
if $msg<message>{$key} {
%index<lastkey_>{ $key }{ $msg<message>{$key} } = $msg<topic> ;
%index<idx_>{ $key }{ $msg<message>{$key} }{ $msg<topic> } = 1 ;
}
}
spurt "$dbfile.json", to-json(%db);
spurt "{$dbfile}_index.json", to-json(%index);
}
when 'get' {
%response<topic> = $msg<topic> ;
%response<message> = %db{ $msg<topic> } ;
%response<status> = 'ok' ;
}
when 'dump' {
%response{'data'} = %db ;
%response<status> = 'ok' ;
}
when 'dumpindex' {
%response{'data'} = %index ;
%response<status> = 'ok' ;
}
when 'delete' {
%db{ $msg<topic> }:delete;
%response<status> = 'ok' ;
spurt "$dbfile.json", to-json(%db);
reindex();
}
when 'addindex' {
%response<status> = 'ok' ;
%index<keys_>{ $msg<key>} =1 ;
reindex();
}
when 'reportlast' {
%response{'data'} = %db{%index<last_>} ;
%response<status> = 'ok' ;
}
when 'reportlastindex' {
%response<key> = $msg<key> ;
for %index<lastkey_>{$msg<key>}.keys -> $value {
#%response{'data'}.push: %db{ %index<lastkey_>{ $msg<key> }{ $value } } ;
%response{'data'}{$value} = %db{ %index<lastkey_>{ $msg<key> }{ $value } } ;
}
%response<status> = 'ok' ;
}
when 'reportindex' {
%response<status> = 'ok' ;
for %index<idx_>{$msg<key>}.keys.sort -> $value {
for %index<idx_>{ $msg<key> }{ $value }.keys.sort -> $topic {
%response<data>.push: %db{ $topic } ;
#%response<data>{$value} = %db{ $topic } ;
}
}
}
when 'commit' {
spurt "$dbfile.json", to-json(%db);
spurt "{$dbfile}_index.json", to-json(%index);
%response<status> = 'ok' ;
}
default {
%response<status> = 'error';
%response<error> = 'no function or not supported';
}
}
$conn.print( to-json(%response, :!pretty) ~ "\n" ) ;
LAST { $conn.close ; }
QUIT { default { $conn.close ; say "oh no, $_";}}
CATCH { default { say .^name, ': ', .Str , " handled in $?LINE";}}
}
}
}
sub reindex {
%index<idx_>:delete;
for %db.keys -> $topic {
my $msg = %db{$topic} ;
for %index<keys_>.keys -> $key {
if $msg{$key} {
%index<idx_>{ $key }{ $msg{$key} }{ $topic } = 1 ;
}
}
}
spurt "{$dbfile}_index.json", to-json(%index) ;
}
}</syntaxhighlight>
<b>client.raku:</b>
<syntaxhighlight lang="raku" line>#!/usr/bin/env raku
use JSON::Fast ;
multi MAIN('set', $topic, $message='', :$server='localhost', :$port='3333', :$json='') {
my %msg = function => 'set' , topic=> $topic , message=> $message ;
%msg{"message"} = from-json( $json ) if $json ;
sendmsg( %msg , $server, $port) ;
}
multi MAIN('add', $topic, $json, :$server='localhost', :$port='3333' ) {
my %msg = function => 'set' , topic=> $topic;
%msg{"message"} = from-json( $json ) if $json ;
sendmsg( %msg , $server, $port) ;
}
multi MAIN('get', $topic, :$server='localhost', :$port='3333') {
my %msg = function => 'get' , topic=> $topic ;
sendmsg( %msg , $server, $port) ;
}
multi MAIN('delete', $topic, :$server='localhost', :$port='3333') {
my %msg = function => 'delete' , topic=> $topic ;
sendmsg( %msg , $server, $port) ;
}
multi MAIN('dump', :$server='localhost', :$port='3333') {
my %msg = function => 'dump' ;
sendmsg( %msg , $server, $port) ;
}
multi MAIN('addindex', $key, :$server='localhost', :$port='3333') {
my %msg = function => 'addindex', key => $key ;
sendmsg( %msg , $server, $port) ;
}
multi MAIN('reportindex', $key, :$server='localhost', :$port='3333') {
my %msg = function => 'reportindex', key => $key ;
sendmsg( %msg , $server, $port) ;
}
multi MAIN('reportlastindex', $key, :$server='localhost', :$port='3333') {
my %msg = function => 'reportlastindex', key => $key ;
sendmsg( %msg , $server, $port) ;
}
multi MAIN('reportlast', :$server='localhost', :$port='3333') {
my %msg = function => 'reportlast' ;
sendmsg( %msg , $server, $port) ;
}
sub sendmsg( %msg , $server, $port){
my $conn = await IO::Socket::Async.connect( $server , $port );
$conn.print: to-json( %msg,:!pretty)~"\n";
react {
whenever $conn.Supply -> $data {
print $data;
$conn.close;
}
}
}</syntaxhighlight>
Example:
<pre>./client.raku addindex constructor
./client.raku addindex date
 
./client.raku add 2007 '{"date":"2007-11-04","constructor":"Ducati","name":"Casey Stoner"}'
./client.raku add 2008 '{"date":"2008-10-26","constructor":"Yamaha","name":"Valentino Rossi"}'
./client.raku add 2009 '{"date":"2009-11-08","constructor":"Yamaha","name":"Valentino Rossi"}'
./client.raku add 2010 '{"date":"2010-11-17","constructor":"Yamaha","name":"Jorge Lorenzo"}'
./client.raku add 2011 '{"date":"2011-11-06","constructor":"Honda","name":"Casey Stoner"}'
./client.raku add 2012 '{"date":"2012-11-11","constructor":"Yamaha","name":"Jorge Lorenzo"}'
./client.raku add 2013 '{"date":"2013-11-10","constructor":"Honda","name":"Marc Márquez"}'
./client.raku add 2014 '{"date":"2014-11-09","constructor":"Honda","name":"Marc Márquez"}'
./client.raku add 2015 '{"date":"2015-11-08","constructor":"Yamaha","name":"Jorge Lorenzo"}'
./client.raku add 2016 '{"date":"2016-11-13","constructor":"Honda","name":"Marc Márquez"}'
./client.raku add 2017 '{"date":"2017-11-12","constructor":"Honda","name":"Marc Márquez"}'
 
./client.raku reportlast
./client.raku reportlastindex constructor
./client.raku reportindex date</pre>
 
=={{header|REBOL}}==
<langsyntaxhighlight lang="rebol">rebol [author: "Nick Antonaccio"]
write/append %rdb "" db: load %rdb
switch system/options/args/1 [
Line 3,454 ⟶ 4,430:
"sort" [probe sort/skip db 4]
]
halt</langsyntaxhighlight>
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/* REXX ---------------------------------------------------------------
* 05.10.2014
*--------------------------------------------------------------------*/
Line 3,532 ⟶ 4,509:
Say 'end to end this program'
Say 'Use category - to list items without category'
Return</langsyntaxhighlight>
{{out}}
<pre> Enter your commands, ?, or end
Line 3,569 ⟶ 4,546:
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">require 'date'
require 'json'
require 'securerandom'
Line 3,755 ⟶ 4,732:
end
 
process_command_line *ARGV</langsyntaxhighlight>
 
Sample session
Line 3,833 ⟶ 4,810:
</pre>
 
=={{header|Run BASIC}}==
<lang runbasic>sqliteconnect #sql, "f:\client.db" ' Connect to the DB
 
' -------------------------------
' show user options
' -------------------------------
[sho]
cls ' clear screen
button #acd, "Add a new entry", [add]
button #acd, "Print the latest entry", [last]
button #acd, "Print the latest entry for each category", [lastCat]
button #acd, "Print all entries sorted by a date", [date]
button #ex, "Exit", [exit]
wait
 
' ------------------------------------
' add a new entry (user input screen)
' ------------------------------------
[add]
cls ' clear the screen
html "<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 bgcolor=wheat>"
html "<TR align=center BGCOLOR=tan><TD colspan=2>Client Maintenance</TD></TR><TR>"
html "<TD bgcolor=tan align=right>Client Num</TD><TD>"
textbox #clientNum,clientNum$,5
 
html "</TD></TR><TR><TD bgcolor=tan align=right>Name</TD><TD>"
textbox #name,name$,30
 
html "</TD></TR><TR><TD bgcolor=tan align=right>Client Date</TD><TD>"
textbox #clientDate,clientDate$,19
 
html "</TD></TR><TR><TD bgcolor=tan align=right>Category</TD><TD>"
textbox #category,category$,10
 
html "</TD></TR><TR><TR bgcolor=tan><TD colspan=2 ALIGN=CENTER>"
button #acd, "Add", [addIt]
button #ex, "Exit", [sho]
html "</TD></TR></TABLE>"
wait
 
' ---------------------------------------------
' Get data from the screen
' ---------------------------------------------
[addIt]
clientNum = #clientNum contents$()
name$ = trim$(#name contents$())
clientDate$ = trim$(#clientDate contents$())
category$ = trim$(#category contents$())
dbVals$ = clientNum;",'";name$;"','";clientDate$;"','";category$;"'"
sql$ = "INSERT into client VALUES ("; dbVals$ ; ")"
#sql execute(sql$)
goto [sho]
 
' ------------------------------------
' Select last entry
' ------------------------------------
[last]
sql$ = "SELECT *,client.rowid as rowid FROM client ORDER BY rowid desc LIMIT 1"
what$ = "---- Last Entry ----"
goto [shoQuery]
 
' ------------------------------------
' Select by category (Last date only)
' ------------------------------------
[lastCat]
sql$ = "SELECT * FROM client
WHERE client.clientDate = (SELECT max(c.clientDate)
FROM client as c WHERE c.category = client.category)
ORDER BY category"
what$ = "---- Last Category Sequence ----"
goto [shoQuery]
 
' ------------------------------------
' Select by date
' ------------------------------------
[date]
sql$ = "SELECT * FROM client ORDER BY clientDate"
what$ = "---- By Date ----"
 
[shoQuery]
cls
print what$
html "<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0>"
html "<TR align=center bgcolor=wheat><TD>Client<br>Num</TD><TD>Name</TD><TD>Client<br>Date</TD><TD>Category</TD></TR>" ' heading
#sql execute(sql$)
WHILE #sql hasanswer()
#row = #sql #nextrow()
clientNum = #row clientNum()
name$ = #row name$()
clientDate$ = #row clientDate$()
category$ = #row category$()
 
html "<TR><TD align=right>";clientNum;"</TD><TD>";name$;"</TD><TD>";clientDate$;"</TD><TD>";category$;"</TD></TR>"
WEND
html "</TABLE>"
button #c, "Continue", [sho]
wait
 
' ------ the end -------
[exit]
end</lang>
Output:
 
---- User Input ----<br />
<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 bgcolor=wheat>
<TR align=center BGCOLOR=tan><TD colspan=2>Client Maintenance</TD></TR>
<TR><TD bgcolor=tan align=right>Client Num</TD><TD>5</TD></TR>
<TR><TD bgcolor=tan align=right>Name</TD><TD>Dawnridge Winery</TD></TR>
<TR><TD bgcolor=tan align=right>Client Date</TD><TD>2008-06-18 22:16</TD></TR>
<TR><TD bgcolor=tan align=right>Category</TD><TD>wine</TD></TR>
<TR><TR bgcolor=tan><TD colspan=2 ALIGN=CENTER>[Add] [Exit]</TD></TR></TABLE>
 
---- Last Entry ----<br />
<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0>
<TR align=center bgcolor=wheat><TD>Client<br>Num</TD><TD>Name</TD><TD>Client<br>Date</TD><TD>Category</TD></TR>
<TR><TD align=right>5</TD><TD>Dawnridge Winery</TD><TD>2008-06-18 22:16</TD><TD>wine</TD></TR></TABLE>
 
---- Last category Sequence ----<br />
<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0>
<TR align=center bgcolor=wheat><TD>Client<br>Num</TD><TD>Name</TD><TD>Client<br>Date</TD><TD>Category</TD></TR>
<TR><TD align=right>1</TD><TD>Home Sales</TD><TD>2012-01-01 10;20</TD><TD>broker</TD></TR>
<TR><TD align=right>4</TD><TD>Back 40 Equipment</TD><TD>2009-09-18 20:18</TD><TD>farm</TD></TR>
<TR><TD align=right>3</TD><TD>Floral Designs</TD><TD>2010-10-14 09:16</TD><TD>flowers</TD></TR>
<TR><TD align=right>2</TD><TD>Best Foods</TD><TD>2011-02-02 12:33</TD><TD>food</TD></TR>
<TR><TD align=right>5</TD><TD>Dawnridge Winery</TD><TD>2008-06-18 22:16</TD><TD>wine</TD></TR></TABLE>
 
---- Date Sequence ----<br />
<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0>
<TR align=center bgcolor=wheat><TD>Client<br>Num</TD><TD>Name</TD><TD>Client<br>Date</TD><TD>Category</TD></TR>
<TR><TD align=right>5</TD><TD>Dawnridge Winery</TD><TD>2008-06-18 22;16</TD><TD>wine</TD></TR>
<TR><TD align=right>4</TD><TD>Back 40 Equipment</TD><TD>2009-09-18 20:18</TD><TD>farm</TD></TR>
<TR><TD align=right>3</TD><TD>Floral Designs</TD><TD>2010-10-14 09:16</TD><TD>flowers</TD></TR>
<TR><TD align=right>2</TD><TD>Best Foods</TD><TD>2011-02-02 12:33</TD><TD>food</TD></TR>
<TR><TD align=right>1</TD><TD>Home Sales</TD><TD>2012-01-01 10:20</TD><TD>broker</TD></TR></TABLE>
=={{header|Scala}}==
<langsyntaxhighlight Scalalang="scala">object SimpleDatabase extends App {
type Entry = Array[String]
def asTSV(e: Entry) = e mkString "\t"
Line 4,005 ⟶ 4,848:
case _ => println("Usage: SimpleDatabase filename.tsv [all [latest]| latest [CATEGORY] | add [DESCRIPTION [CATEGORY [OPTIONAL]...]]]")
}
}</langsyntaxhighlight>
{{out}}
<pre>> SimpleDatabase
Line 4,043 ⟶ 4,886:
=={{header|Tcl}}==
The format used is that of a Tcl dictionary, where each entry uses the title as a key and the remaining information (category, date and miscellaneous metadata) is the value associated with it. The only variation from the standard internal format is that entries are separated by newlines instead of spaces; this is still a legal value, but is a non-canonical.
<langsyntaxhighlight lang="tcl">#!/usr/bin/env tclsh8.6
package require Tcl 8.6
namespace eval udb {
Line 4,143 ⟶ 4,986:
}
 
udb::Store [lindex $argv 0]</langsyntaxhighlight>
Sample session:
<langsyntaxhighlight lang="bash">bash$ udb.tcl db
wrong # args: should be "udb.tcl dbfile subcommand ?args...?"
bash$ udb.tcl db ?
Line 4,235 ⟶ 5,078:
Title: Title 3
Category: bar
Date: Tue Nov 15 18:12:07 GMT 2011</langsyntaxhighlight>
 
=={{header|ToffeeScript}}==
<langsyntaxhighlight lang="coffeescript">#!/usr/local/bin/toffee
 
prog = require 'commander'
Line 4,322 ⟶ 5,165:
printFormatted entry
 
prog.parse process.argv</langsyntaxhighlight>
 
=={{header|UNIX Shell}}==
This format is guaranteed to be human readable: if you can type it, you can read it.
<langsyntaxhighlight lang="bash">#!/bin/sh
 
db_create() {
Line 4,421 ⟶ 5,264:
show_help
;;
esac</langsyntaxhighlight>
Sample usage (assuming script is named "sdb"):<syntaxhighlight lang="text">$ sdb create CDs
Create DB `CDs'
$ sdb add CDs Bookends
Line 4,458 ⟶ 5,301:
$ sdb drop CDs
Delete DB `CDs'
$</langsyntaxhighlight>
 
=={{header|Wren}}==
{{trans|Kotlin}}
===Version 1===
{{libheader|Wren-ioutil}}
{{libheader|Wren-trait}}
{{libheader|Wren-iterate}}
{{libheader|Wren-date}}
{{libheader|Wren-sort}}
{{libheader|Wren-str}}
Note that since Wren CLI currently has no way of determining the current date/time, a date needs to be input for each item to be added.
<syntaxhighlight lang="wren">/* Simple_database.wren */
 
import "os" for Process
import "./ioutil" for File, FileFlags, FileUtil
import "./trait" for Comparable
import "./iterate" for Reversed
import "./date" for Date
import "./sort" for Sort
import "./str" for Str
 
var fileName = "Simple_database.csv"
 
Date.default = Date.isoDate
 
class Item is Comparable {
construct new(name, date, category) {
_name = name
_date = date
_category = category
}
 
name { _name }
date { _date }
category { _category }
 
compare(other) { _date.compare(other.date) }
 
toString { "%(name), %(date.toString), %(category)" }
}
 
var printUsage = Fn.new {
System.print("""
Usage:
wren Simple_database.wren cmd [categoryName]
add add item name and date, followed by optional category
latest print item with latest date, followed by optional category
all print all
For instance: add "some item name", "some item date", "some category name"
Dates should be in format: yyyy-mm-dd
""")
}
 
var load = Fn.new {
var db = []
var lines = FileUtil.readLines(fileName)
for (line in lines) {
if (line == "") break // end of file
var item = line.split(", ")
db.add(Item.new(item[0], Date.parse(item[1]), item[2]))
}
return db
}
 
var store = Fn.new { |item|
File.openWithFlags(fileName, FileFlags.writeOnly) { |f|
f.writeBytes("%(item)\n")
}
}
 
var addItem = Fn.new { |input|
if (input.count < 2) {
printUsage.call()
return
}
var date = Date.parse(input[1])
var cat = (input.count == 3) ? input[2] : "none"
store.call(Item.new(input[0], date, cat))
}
 
var printLatest = Fn.new { |a|
var db = load.call()
if (db.isEmpty) {
System.print("No entries in database.")
return
}
Sort.quick(db) // sort by ascending date
if (a.count == 1) {
var found = false
for (item in Reversed.new(db)) {
if (item.category == a[0]) {
System.print(item)
found = true
break
}
}
if (!found) System.print("There are no items for category '%(a[0])'.")
} else System.print(db[-1])
}
 
var printAll = Fn.new {
var db = load.call()
if (db.isEmpty) {
System.print("No entries in database.")
return
}
Sort.quick(db) // sort by ascending date
for (item in db) System.print(item)
}
 
var args = Process.arguments
if (!(1..4).contains(args.count)) {
printUsage.call()
return
}
// create file if it doesn't already exist
if (!File.exists(fileName)) {
var f = File.create(fileName)
f.close()
}
 
var cmd = Str.lower(args[0])
if (cmd == "add") {
addItem.call(args[1..-1])
} else if (cmd == "latest") {
printLatest.call(args[1..-1])
} else if (cmd == "all") {
printAll.call()
} else {
printUsage.call()
}</syntaxhighlight>
 
{{out}}
Sample session:
<pre>
$ wren Simple_database.wren add item1 2021-03-01
$ wren Simple_database.wren add item2 2021-04-01
$ wren Simple_database.wren add item3 2021-05-01 cat3
$ wren Simple_database.wren add item4 2021-06-01 cat3
$ wren Simple_database.wren add item5 2021-07-01 cat3
$ wren Simple_database.wren latest
item5, 2021-07-01, cat3
$ wren Simple_database.wren latest none
item2, 2021-04-01, none
$ wren Simple_database.wren latest cat4
There are no items for category 'cat4'.
$ wren Simple_database.wren all
item1, 2021-03-01, none
item2, 2021-04-01, none
item3, 2021-05-01, cat3
item4, 2021-06-01, cat3
item5, 2021-07-01, cat3
</pre>
<br>
===Version 2===
{{libheader|Wren-table}}
The above module provides a more generic way to create simple databases and was not available when the first version was written.
<syntaxhighlight lang="wren">import "os" for Process
import "./table" for Table, FieldInfo, File
import "./str" for Str
 
var printUsage = Fn.new {
System.print("""
Usage:
wren Simple_database.wren cmd [categoryName]
add add item name and date, followed by optional category
latest print item with latest date, followed by optional category
all print all
For instance: add "some item name", "some item date", "some category name"
Dates should be in format: yyyy-mm-dd
""")
}
 
var printLatest = Fn.new { |table, a|
if (table.isEmpty) {
System.print("No entries in table.")
return
}
var records = table.records
records.sort { |s, t| Str.lt(s[1], t[1]) } // sort by ascending date
if (a.count == 1) {
var found = false
for (record in records[-1..0]) {
if (record[2] == a[0]) {
System.print(record)
found = true
break
}
}
if (!found) System.print("There are no records for category '%(a[0])'.")
} else System.print(records[-1])
}
 
var args = Process.arguments
if (!(1..4).contains(args.count)) {
printUsage.call()
return
}
 
// create a new Table object
var tableName = "Simple_database"
var table
if (Table.fileExists(tableName)) {
table = Table.load(tableName)
} else {
var fis = [
FieldInfo.new("name", String),
FieldInfo.new("date", String),
FieldInfo.new("category", String)
]
table = Table.new(tableName, fis)
}
 
var cmd = Str.lower(args[0])
if (cmd == "add") {
if (args.count < 4) args.add("none")
table.add(args[1..-1])
table.save()
} else if (cmd == "latest") {
printLatest.call(table, args[1..-1])
} else if (cmd == "all") {
table.list()
} else {
printUsage.call()
}</syntaxhighlight>
 
{{out}}
<pre>
$ wren Simple_database.wren add item1 2021-03-01
$ wren Simple_database.wren add item2 2021-04-01
$ wren Simple_database.wren add item3 2021-05-01 cat3
$ wren Simple_database.wren add item4 2021-06-01 cat3
$ wren Simple_database.wren add item5 2021-07-01 cat3
$ wren Simple_database.wren latest
[item5, 2021-07-01, cat3]
$ wren Simple_database.wren latest none
[item2, 2021-04-01, none]
$ wren Simple_database.wren latest cat4
There are no records for category 'cat4'.
$ wren Simple_database.wren all
Records in 'Simple_database' table:
 
name date category
----- ---------- --------
item1 2021-03-01 none
item2 2021-04-01 none
item3 2021-05-01 cat3
item4 2021-06-01 cat3
item5 2021-07-01 cat3
</pre>
413

edits