Task: Simple database

C: #include <stdio.h>
#include <stdlib.h> 
#include <string.h> 
#define _XOPEN_SOURCE 
#define __USE_XOPEN
#include <time.h>
#define DB "database.csv" 
#define TRY(a)  if (!(a)) {perror(#a);exit(1);}
#define TRY2(a) if((a)<0) {perror(#a);exit(1);}
#define FREE(a) if(a) {free(a);a=NULL;}
#define sort_by(foo) \
static int by_##foo (const void*p1, const void*p2) { \
    return strcmp ((*(const pdb_t*)p1)->foo, (*(const pdb_t*)p2)->foo); }
typedef struct db {
    char title[26];
    char first_name[26];
    char last_name[26];
    time_t date;
    char publ[100];
    struct db *next;
}
db_t,*pdb_t;
typedef int (sort)(const void*, const void*);
enum {CREATE,PRINT,TITLE,DATE,AUTH,READLINE,READ,SORT,DESTROY};
static pdb_t dao (int cmd, FILE *f, pdb_t db, sort sortby);
static char *time2str (time_t *time);
static time_t str2time (char *date);

sort_by(last_name);
sort_by(title);
static int by_date(pdb_t *p1, pdb_t *p2);

int main (int argc, char **argv) {
    char buf[100];
    const char *commands[]={"-c", "-p", "-t", "-d", "-a", NULL};
    db_t db;
    db.next=NULL;
    pdb_t dblist;
    int i;
    FILE *f;
    TRY (f=fopen(DB,"a+"));
    if (argc<2) {
usage:  printf ("Usage: %s [commands]\n"
        "-c  Create new entry.\n"
        "-p  Print the latest entry.\n"
        "-t  Print all entries sorted by title.\n"
        "-d  Print all entries sorted by date.\n"
        "-a  Print all entries sorted by author.\n",argv[0]);
        fclose (f);
        return 0;
    }
    for (i=0;commands[i]&&strcmp(argv[1],commands[i]);i++);
    switch (i) {
        case CREATE:
        printf("-c  Create a new entry.\n");
        printf("Title           :");if((scanf(" %25[^\n]",db.title     ))<0)break;
        printf("Author Firstname:");if((scanf(" %25[^\n]",db.first_name))<0)break;
        printf("Author Lastname :");if((scanf(" %25[^\n]",db.last_name ))<0)break;
        printf("Date 10-12-2000 :");if((scanf(" %10[^\n]",buf          ))<0)break;
        printf("Publication     :");if((scanf(" %99[^\n]",db.publ      ))<0)break;
        db.date=str2time (buf);
        dao (CREATE,f,&db,NULL);
        break;
        case PRINT:
        printf ("-p  Print the latest entry.\n");
        while (!feof(f)) dao (READLINE,f,&db,NULL);
        dao (PRINT,f,&db,NULL);
        break;
        case TITLE:
        printf ("-t  Print all entries sorted by title.\n");
        dblist = dao (READ,f,&db,NULL);
        dblist = dao (SORT,f,dblist,by_title);
        dao (PRINT,f,dblist,NULL);
        dao (DESTROY,f,dblist,NULL);
        break;
        case DATE:
        printf ("-d  Print all entries sorted by date.\n");
        dblist = dao (READ,f,&db,NULL);
        dblist = dao (SORT,f,dblist,(int (*)(const void *,const  void *)) by_date);
        dao (PRINT,f,dblist,NULL);
        dao (DESTROY,f,dblist,NULL);
        break;
        case AUTH:
        printf ("-a  Print all entries sorted by author.\n");
        dblist = dao (READ,f,&db,NULL);
        dblist = dao (SORT,f,dblist,by_last_name);
        dao (PRINT,f,dblist,NULL);
        dao (DESTROY,f,dblist,NULL);
        break;
        default: {
            printf ("Unknown command: %s.\n",strlen(argv[1])<10?argv[1]:"");
            goto usage;
    }   }
    fclose (f);
    return 0;
}

static pdb_t dao (int cmd, FILE *f, pdb_t in_db, sort sortby) {
    pdb_t *pdb=NULL,rec=NULL,hd=NULL;
    int i=0,ret;
    char buf[100];
    switch (cmd) {
        case CREATE:
        fprintf (f,"\"%s\",",in_db->title);
        fprintf (f,"\"%s\",",in_db->first_name);
        fprintf (f,"\"%s\",",in_db->last_name);
        fprintf (f,"\"%s\",",time2str(&in_db->date));
        fprintf (f,"\"%s\" \n",in_db->publ);
        break;
        case PRINT:
        for (;in_db;i++) {
            printf ("Title       : %s\n",     in_db->title);
            printf ("Author      : %s %s\n",  in_db->first_name, in_db->last_name);
            printf ("Date        : %s\n",     time2str(&in_db->date));
            printf ("Publication : %s\n\n",   in_db->publ);
            if (!((i+1)%3)) {
                printf ("Press Enter to continue.\n");
                ret = scanf ("%*[^\n]");
                if (ret<0) return rec; 
                else getchar();
            }
            in_db=in_db->next;
        }
        break;
        case READLINE:
        if((fscanf(f," \"%[^\"]\",",in_db->title     ))<0)break;
        if((fscanf(f," \"%[^\"]\",",in_db->first_name))<0)break;
        if((fscanf(f," \"%[^\"]\",",in_db->last_name ))<0)break;
        if((fscanf(f," \"%[^\"]\",",buf              ))<0)break;
        if((fscanf(f," \"%[^\"]\" ",in_db->publ      ))<0)break;
        in_db->date=str2time (buf);
        break;
        case READ:
        while (!feof(f)) {
            dao (READLINE,f,in_db,NULL);
            TRY (rec=malloc(sizeof(db_t)));
            *rec=*in_db; 
            rec->next=hd;
            hd=rec;i++;
        }
        if (i<2) {
            puts ("Empty database. Please create some entries.");
            fclose (f);
            exit (0);
        }
        break;
        case SORT:
        rec=in_db;
        for (;in_db;i++) in_db=in_db->next;
        TRY (pdb=malloc(i*sizeof(pdb_t)));
        in_db=rec;
        for (i=0;in_db;i++) {
            pdb[i]=in_db;
            in_db=in_db->next;
        }
        qsort (pdb,i,sizeof in_db,sortby);
        pdb[i-1]->next=NULL;
        for (i=i-1;i;i--) {
            pdb[i-1]->next=pdb[i];
        }
        rec=pdb[0];
        FREE (pdb);
        pdb=NULL;
        break;
        case DESTROY: {
            while ((rec=in_db)) {
                in_db=in_db->next;
                FREE (rec);
    }   }   }
    return rec;
}

static char *time2str (time_t *time) {
    static char buf[255];
    struct tm *ptm;
    ptm=localtime (time);
    strftime(buf, 255, "%m-%d-%Y", ptm);
    return buf;
}

static time_t str2time (char *date) {
    struct tm tm;
    memset (&tm, 0, sizeof(struct tm));
    strptime(date, "%m-%d-%Y", &tm);
    return mktime(&tm);
}

static int by_date (pdb_t *p1, pdb_t *p2) {
    if ((*p1)->date < (*p2)->date) {
        return -1;
    }
    else return ((*p1)->date > (*p2)->date);
}





Java: import java.io.*;
import java.text.*;
import java.util.*;

public class SimpleDatabase {

    final static String filename = "simdb.csv";

    public static void main(String[] args) {
        if (args.length < 1 || args.length > 3) {
            printUsage();
            return;
        }

        switch (args[0].toLowerCase()) {
            case "add":
                addItem(args);
                break;
            case "latest":
                printLatest(args);
                break;
            case "all":
                printAll();
                break;
            default:
                printUsage();
                break;
        }
    }

    private static class Item implements Comparable<Item>{
        final String name;
        final String date;
        final String category;

        Item(String n, String d, String c) {
            name = n;
            date = d;
            category = c;
        }

        @Override
        public int compareTo(Item item){
            return date.compareTo(item.date);
        }

        @Override
        public String toString() {
            return String.format("%s,%s,%s%n", name, date, category);
        }
    }

    private static void addItem(String[] input) {
        if (input.length < 2) {
            printUsage();
            return;
        }
        List<Item> db = load();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = sdf.format(new Date());
        String cat = (input.length == 3) ? input[2] : "none";
        db.add(new Item(input[1], date, cat));
        store(db);
    }

    private static void printLatest(String[] a) {
        List<Item> db = load();
        if (db.isEmpty()) {
            System.out.println("No entries in database.");
            return;
        }
        Collections.sort(db);
        if (a.length == 2) {
            for (Item item : db)
                if (item.category.equals(a[1]))
                    System.out.println(item);
        } else {
            System.out.println(db.get(0));
        }
    }

    private static void printAll() {
        List<Item> db = load();
        if (db.isEmpty()) {
            System.out.println("No entries in database.");
            return;
        }
        Collections.sort(db);
        for (Item item : db)
            System.out.println(item);
    }

    private static List<Item> load() {
        List<Item> db = new ArrayList<>();
        try (Scanner sc = new Scanner(new File(filename))) {
            while (sc.hasNext()) {
                String[] item = sc.nextLine().split(",");
                db.add(new Item(item[0], item[1], item[2]));
            }
        } catch (IOException e) {
            System.out.println(e);
        }
        return db;
    }

    private static void store(List<Item> db) {
        try (FileWriter fw = new FileWriter(filename)) {
            for (Item item : db)
                fw.write(item.toString());
        } catch (IOException e) {
            System.out.println(e);
        }
    }

    private static void printUsage() {
         System.out.println("Usage:");
         System.out.println("  simdb cmd [categoryName]");
         System.out.println("  add     add item, followed by optional category");
         System.out.println("  latest  print last added item(s), followed by "
                 + "optional category");
         System.out.println("  all     print all");
         System.out.println("  For instance: add \"some item name\" "
                 + "\"some category name\"");
    }
}