Created first project saving it and reading from .pit file!

This commit is contained in:
Mike Dvorkin
2010-07-14 22:30:53 -07:00
parent dab0f2f9bb
commit cafced4b36
18 changed files with 310 additions and 62 deletions

26
src/activity.c Normal file
View File

@@ -0,0 +1,26 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include "pit.h"
#include "activity.h"
ulong subject_id; /* Reference to the specific Project, Task, or Note. */
char subject[16]; /* Project, Task, or Note. */
char message[255]; /* Log message. */
ulong created_by; /* Who added log message? */
time_t created_at; /* When log message was added? */
PActivity pit_add_activity(ulong id, char *subject, char *message, ulong user_id) {
static Activity activity;
memset(&activity, 0, sizeof(activity));
activity.subject_id = id;
activity.created_by = user_id;
activity.created_at = time(NULL);
strncpy(activity.subject, subject, sizeof(activity.subject) - 1);
strncpy(activity.message, message, sizeof(activity.message) - 1);
return &activity;
}

1
src/activity.h Normal file
View File

@@ -0,0 +1 @@
PActivity pit_add_activity(ulong id, char *subject, char *message, ulong user_id);

BIN
src/activity.o Normal file

Binary file not shown.

54
src/db.c Normal file
View File

@@ -0,0 +1,54 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include "pit.h"
#include "db.h"
#include "activity.h"
#include "user.h"
#define PITFILE "/tmp/.pit"
void pit_db_load() {
FILE *pitfile = fopen(PITFILE, "r");
if (pitfile) {
projects = pit_table_load(pitfile);
tasks = pit_table_load(pitfile);
notes = pit_table_load(pitfile);
activities = pit_table_load(pitfile);
users = pit_table_load(pitfile);
fclose(pitfile);
} else {
pit_db_initialize();
}
}
void pit_db_initialize() {
projects = pit_table_initialize(sizeof(Project), TABLE_HAS_ID | TABLE_HAS_TIMESTAMPS);
tasks = pit_table_initialize(sizeof(Task), TABLE_HAS_ID | TABLE_HAS_TIMESTAMPS);
notes = pit_table_initialize(sizeof(Note), TABLE_HAS_ID | TABLE_HAS_TIMESTAMPS);
activities = pit_table_initialize(sizeof(Activity), TABLE_HAS_CREATED_AT);
users = pit_table_initialize(sizeof(User), TABLE_HAS_ID);
pit_table_insert(users, (uchar *)pit_current_user());
pit_table_insert(activities, (uchar *)pit_add_activity(0, "", "Initialized pit", 1));
pit_db_save();
}
void pit_db_save() {
FILE *pitfile = fopen(PITFILE, "wb");
if (!pitfile) {
die_with_errno(PITFILE);
} else {
pit_table_save(pitfile, projects);
pit_table_save(pitfile, tasks);
pit_table_save(pitfile, notes);
pit_table_save(pitfile, activities);
pit_table_save(pitfile, users);
fclose(pitfile);
}
}

7
src/db.h Normal file
View File

@@ -0,0 +1,7 @@
#if !defined(__DB_H__)
#define __DB_H__
void pit_db_load();
void pit_db_save();
void pit_db_initialize();
#endif

View File

@@ -1,21 +1,45 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include "pit.h"
#include "project.h"
#include "task.h"
PTable projects;
PTable tasks;
PTable notes;
PTable activities;
PTable users;
static int usage() {
printf("usage...\n");
return 1;
}
void die(char *msg)
{
fprintf(stderr, "pit (fatal): %s\n", msg);
exit(0);
}
void die_with_errno(char *prefix)
{
fprintf(stderr, "pit (fatal): %s: ", prefix);
perror(NULL);
exit(0);
}
int main(int argc, char *argv[]) {
int i;
char *commands[] = { "project", "task", "note", "log" };
/***
int i;
printf("argc: %d\n", argc);
for(i = 0; i < argc; i++) {
printf("argv[%d]: [%s]\n", i, argv[i]);
}
***/
if (argc > 1) {
if (strstr(commands[0], argv[1]) == commands[0]) {

View File

@@ -1,10 +1,75 @@
#if !defined(__PIT_H__)
#define __PIT_H__
typedef unsigned int uint;
typedef unsigned long ulong;
typedef unsigned char uchar;
int pit_project(char *argv[]);
int pit_task(char *argv[]);
#include "table.h"
typedef struct {
ulong id;
int current; /* 1 if the project is current, 0 otherwise. */
char name[128]; /* Project name. */
char status[16]; /* Project status. */
ulong number_of_open_tasks; /* Number of open tasks. */
ulong number_of_closed_tasks; /* Number of closed tasks. */
ulong closed_by; /* Who closed the project? */
ulong created_by; /* Who created the project? */
ulong updated_by; /* Who last updated the project? */
time_t closed_at; /* When the project was closed? */
time_t created_at; /* When the project was created? */
time_t updated_at; /* When the project was last updated? */
} Project, *PProject;
typedef struct {
ulong id;
ulong project_id; /* Which project the task belongs to? */
int current; /* 1 if the task is current, 0 otherwise. */
int priority; /* Task priority. */
char name[128]; /* Task name. */
char status[16]; /* Task status. */
time_t deadline; /* Task deadline. */
ulong number_of_notes; /* Number of notes. */
ulong closed_by; /* Who closed the task? */
ulong created_by; /* Who created the task? */
ulong updated_by; /* Who last updated the task? */
time_t closed_at; /* When the task was closed? */
time_t created_at; /* When the task was created? */
time_t updated_at; /* When the task was last updated? */
} Task, *PTask;
typedef struct {
ulong id;
ulong task_id; /* Task the note belongs to. */
char message[255]; /* The body of the note. */
ulong created_by; /* Who created the note? */
ulong updated_by; /* Who last updated the note? */
time_t created_at; /* When the note was created? */
time_t updated_at; /* When the note was last updated? */
} Note, *PNote;
typedef struct {
ulong subject_id; /* Reference to the specific Project, Task, or Note. */
char subject[16]; /* Project, Task, or Note. */
char message[255]; /* Log message. */
ulong created_by; /* Who added log message? */
time_t created_at; /* When log message was added? */
} Activity, *PActivity;
typedef struct {
ulong id;
char username[32]; /* Username. */
char email[32]; /* User's email. */
} User, *PUser;
extern PTable projects;
extern PTable tasks;
extern PTable notes;
extern PTable activities;
extern PTable users;
void die(char *msg);
void die_with_errno(char *prefix);
#endif

View File

@@ -1,15 +1,79 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include "pit.h"
#include "db.h"
#include "project.h"
int pit_project(char *argv[]) {
static int already_exist(char *name)
{
ulong i;
PProject pp;
pit_db_load();
for(i = 0, pp = (PProject)projects->slots; i < projects->number_of_records; i++, pp++) {
if (!strcmp(pp->name, name)) {
return 1;
}
}
return 0;
}
static void list_projects()
{
ulong i;
PProject pp;
pit_db_load();
for(i = 0, pp = (PProject)projects->slots; i < projects->number_of_records; i++, pp++) {
printf("%lu: [%s] %s\n", pp->id, pp->status, pp->name);
}
}
static void create_project(char *name, char *status)
{
pit_db_load();
printf("creating project [%s], status [%s]\n", name, status);
if (!already_exist(name)) {
Project p;
memset(&p, 0, sizeof(p));
strncpy(p.name, name, sizeof(p.name) - 1);
strncpy(p.status, status, sizeof(p.status) - 1);
p.current = 1;
p.number_of_open_tasks = 0;
p.number_of_closed_tasks = 0;
p.closed_by = 0;
p.created_by = p.updated_by = 1; // TODO
p.closed_at = 0;
p.created_at = p.updated_at = time(NULL);
pit_table_insert(projects, (uchar *)&p);
pit_db_save();
}
}
static int show_project(unsigned long number)
{
printf("showing project %lu\n", number);
return 1;
}
static int delete_project(unsigned long number)
{
printf("deleting project %lu\n", number);
return 1;
}
int pit_project(char *argv[])
{
char **arg = &argv[1];
char *error = NULL;
if (!*arg) {
printf("list projects\n");
list_projects();
} else if (!strcmp(*arg, "-c")) {
if (!*++arg) {
error = "missing project name";
@@ -39,19 +103,3 @@ int pit_project(char *argv[]) {
return error == NULL;
}
static int create_project(char *name, char *status) {
printf("creating project [%s], status [%s]\n", name, status);
return 1;
}
static int show_project(unsigned long number) {
printf("showing project %lu\n", number);
return 1;
}
static int delete_project(unsigned long number) {
printf("deleting project %lu\n", number);
return 1;
}

View File

@@ -1,8 +1,6 @@
#if !defined(__PROJECT_H__)
#define __PROJECT_H__
static int create_project(char *name, char *status);
static int show_project(unsigned long number);
static int delete_project(unsigned long number);
int pit_project(char *argv[]);
#endif

View File

@@ -3,22 +3,16 @@
#include <string.h>
#include <time.h>
#include "pit.h"
#include "table.h"
#define TABLE_INCREMENT 5
#define TABLE_HAS_ID 1
#define TABLE_HAS_CREATED_AT 2
#define TABLE_HAS_UPDATED_AT 4
#define TABLE_HAS_TIMESTAMPS (TABLE_HAS_CREATED_AT | TABLE_HAS_UPDATED_AT)
/*
** Initialize the table by alloocating necessary memory chunks.
*/
PTable table_initialize(ulong record_size, ulong flags) {
PTable pit_table_initialize(ulong record_size, ulong flags) {
PTable pt;
pt = calloc(1, sizeof(Table));
pt->flags = flags | TABLE_HAS_ID;
pt->flags = flags;
pt->record_size = record_size;
pt->number_of_slots = TABLE_INCREMENT;
pt->number_of_records = 0;
@@ -100,7 +94,8 @@ static PTable table_extend(PTable pt) {
/*
** Find a record by id and return its address.
*/
uchar *table_find(PTable pt, ulong id) {
uchar *pit_table_find(PTable pt, ulong id) {
// TODO: retrn NULL (or raise?) if table doesn't have id.
if (pt->number_of_records == 0 || id <= 0 || id > pt->auto_increment) {
return NULL;
} else {
@@ -112,8 +107,9 @@ uchar *table_find(PTable pt, ulong id) {
** Delete a record by its ID. Return the address of next record or NULL
** if deleted last record.
*/
uchar *table_delete(PTable pt, ulong id) {
register uchar *pr = (uchar *)table_find(pt, id);
uchar *pit_table_delete(PTable pt, ulong id) {
// TODO: retrn NULL (or raise?) if table doesn't have id.
register uchar *pr = (uchar *)pit_table_find(pt, id);
if (pr) {
register ulong i;
@@ -153,7 +149,7 @@ uchar *table_delete(PTable pt, ulong id) {
** Insert a record and return its address. The table gets extended
** as necessary.
*/
uchar *table_insert(PTable pt, uchar *record) {
uchar *pit_table_insert(PTable pt, uchar *record) {
register uchar **pi;
register time_t now;
@@ -191,7 +187,7 @@ uchar *table_insert(PTable pt, uchar *record) {
/*
** Release pt->slots and pt->index memory chunks, then free the table itself.
*/
PTable table_free(PTable pt) {
PTable pit_table_free(PTable pt) {
if (pt) {
if (pt->index) {
free(pt->index);
@@ -209,7 +205,7 @@ PTable table_free(PTable pt) {
** Save the contents of the table to file. The file handle should be
** open with for writing.
*/
int table_save(FILE *file, PTable pt) {
int pit_table_save(FILE *file, PTable pt) {
register int written = 0;
/*
** Save table header data: flags, record_size, number_of_slots,
@@ -227,7 +223,7 @@ int table_save(FILE *file, PTable pt) {
** Load the contents of the table from file. The file handle should be
** open with for reading.
*/
PTable table_load(FILE *file) {
PTable pit_table_load(FILE *file) {
PTable pt;
register int read = 0;
register ulong i;
@@ -241,7 +237,7 @@ PTable table_load(FILE *file) {
/*
** Now allocate slots and index based n original number of slots.
*/
printf("Allocating %lu slots\n", pt->number_of_slots);
/*** printf("Allocating %lu slots\n", pt->number_of_slots); ***/
pt->slots = pr = calloc(pt->number_of_slots, pt->record_size);
pt->index = pi = calloc(pt->number_of_slots, sizeof(uchar *));
/*
@@ -249,6 +245,7 @@ PTable table_load(FILE *file) {
*/
read += fread(pt->slots, pt->record_size, pt->number_of_records, file);
for(i = 0; i < pt->number_of_records; i++, pi++) {
// TODO: if table doesn't have id || has id && id matches...
if ((ulong)*pr == i + 1) {
*pi = pr;
pr += pt->record_size;
@@ -283,7 +280,7 @@ void dump_all(PTable pt) {
Record *prec;
for(i = 1; i <= pt->number_of_slots; i++) {
prec = (Record *)table_find(pt, i);
prec = (Record *)pit_table_find(pt, i);
if (prec) {
dump(prec);
} else {
@@ -298,32 +295,32 @@ int main() {
Record rec, *prec;
ulong i, total = 30;
pt = table_initialize(sizeof(Record), TABLE_HAS_ID | TABLE_HAS_TIMESTAMPS);
pt = pit_table_initialize(sizeof(Record), TABLE_HAS_ID | TABLE_HAS_TIMESTAMPS);
for(i = 0; i < total; i++) {
rec.id = 0;
rec.value = 0x11223344 + i + 1;
strcpy(rec.name, "test");
rec.created_at = rec.updated_at = (time_t)0;
prec = (Record *)table_insert(pt, (uchar *)&rec);
prec = (Record *)pit_table_insert(pt, (uchar *)&rec);
dump(prec);
}
for (i = 20; i < total; i++) {
printf("Deleting %lu\n", i + 1);
prec = (Record *)table_delete(pt, i + 1);
prec = (Record *)pit_table_delete(pt, i + 1);
}
dump_all(pt);
FILE *file = fopen("/tmp/.pit", "w");
table_save(file, pt);
pit_table_save(file, pt);
fclose(file);
file = fopen("/tmp/.pit", "r");
pt = table_load(file);
pt = pit_table_load(file);
dump_all(pt);
fclose(file);
table_free(pt);
pit_table_free(pt);
printf("OK\n");
return 0;
}

Binary file not shown.

View File

@@ -1,6 +1,11 @@
#if !defined(__TABLE_H__)
#define __TABLE_H__
#define TABLE_HAS_ID 1
#define TABLE_HAS_CREATED_AT 2
#define TABLE_HAS_UPDATED_AT 4
#define TABLE_HAS_TIMESTAMPS (TABLE_HAS_CREATED_AT | TABLE_HAS_UPDATED_AT)
typedef struct {
ulong flags; /* Bit mask with table flags */
ulong record_size; /* Record size in bytes; all records are of fixed size */
@@ -11,18 +16,12 @@ typedef struct {
uchar **index; /* Memory chunk to store pointers to individual records, holes for deleted record ids */
} Table, *PTable;
PTable table_initialize(ulong record_size, ulong flags);
PTable table_free(PTable pt);
uchar *table_find(PTable pt, ulong id);
uchar *table_delete(PTable pt, ulong id);
uchar *table_insert(PTable pt, uchar *record);
int table_save(FILE *file, PTable pt);
PTable table_load(FILE *file);
static uchar *table_available_slot(PTable pt);
static uchar *table_last_record(PTable pt);
static uchar **table_available_index(PTable pt);
static uchar **table_last_index(PTable pt);
static PTable table_extend(PTable pt);
PTable pit_table_initialize(ulong record_size, ulong flags);
PTable pit_table_free(PTable pt);
uchar *pit_table_find(PTable pt, ulong id);
uchar *pit_table_delete(PTable pt, ulong id);
uchar *pit_table_insert(PTable pt, uchar *record);
int pit_table_save(FILE *file, PTable pt);
PTable pit_table_load(FILE *file);
#endif

View File

@@ -1,6 +1,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include "pit.h"
#include "task.h"

View File

@@ -1,4 +1,6 @@
#if !defined(__TASK_H__)
#define __TASK_H__
int pit_task(char *argv[]);
#endif

11
src/user.c Normal file
View File

@@ -0,0 +1,11 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include "pit.h"
#include "user.h"
char *pit_current_user() {
return getlogin();
}

1
src/user.h Normal file
View File

@@ -0,0 +1 @@
char *pit_current_user();

BIN
src/user.o Normal file

Binary file not shown.