Commit e168a515 authored by Michael Rouse's avatar Michael Rouse

Fixed linux file handling of the database file. A little messy.

parent 9a788b34
......@@ -149,7 +149,7 @@ Time Slime also defines some helpful directives to easily create these for the c
```c
#define TIMESLIME_DATE_NOW (TIMESLIME_DATE_t){ 0, 0, 0}
#define TIMESLIME_TIME_NOW (TIMESLIME_DATETIME_t){ 0, 0, 0, 0, 0 }
#define TIMESLIME_TIME_NOW (TIMESLIME_DATETIME_t){ 0, 0, 0, -1, -1 }
```
## Report
......@@ -200,6 +200,14 @@ Once build, if you add the executable (in the `build` folder) to your system `PA
> **IMPORTANT**: All dates must be formatted as either `YYYY-MM-DD` or `YYYY/MM/DD`
 
# Todo
- [ ] Better report formatting (done?)
- [ ] Allow second parameter of a report to be "today"
- [ ] Shell program to prompt user for choices if no parameters (or not all parameters) are given (but works on all systems)
- [ ] Imrpove logging
 
......
......@@ -16,8 +16,10 @@ MKDIR = mkdir
ifeq ($(OS),Windows_NT)
RMDIR = cmd /C rmdir /S /Q
CC_FLAGS += -D WINDOWS
else
RMDIR = rmdir -f -r
CC_FLAGS += -D NOTWINDOWS
CC_ENDFLAGS += -ldl
endif
......
......@@ -2,6 +2,7 @@
#include "../string_literals.h"
#include "../logger.h"
args_t args_parse(int argc, char **argv)
{
// Copy the arguments
......@@ -39,6 +40,7 @@ args_t args_parse(int argc, char **argv)
result.modifier3 = args[3];
}
free(args);
return result;
}
......@@ -60,6 +62,9 @@ date_t args_parse_date(char *dateStr)
date.year = 0;
strcpy(date.str, dateStr);
if (strcmp(dateStr, TODAY) == 0)
return date;
char running[256] = "";
int tmp = 0;
int section = YEAR;
......@@ -131,36 +136,66 @@ date_t args_parse_date(char *dateStr)
char* args_get_directory_of_executable(char *name)
{
char path[1000];
char passed_path[PATH_MAX];
#ifndef _WIN32
if (realpath("/proc/self/exe", passed_path) == NULL)
{
printf("realpath error: %s\n", strerror(errno));
return NULL;
}
#else
strcpy(passed_path, name);
#endif
char path[PATH_MAX];
path[0] = '\0';
char read_since_last_separator[100];
char read_since_last_separator[PATH_MAX];
#ifdef _WIN32
read_since_last_separator[0] = '\0';
#else
read_since_last_separator[0] = '/';
read_since_last_separator[1] = '\0';
#endif
char separator;
int i;
int pos;
int len = strlen(name);
int len = strlen(passed_path);
for (i = 0; i < len; i++)
{
if (name[i] == '/' || name[i] == '\\')
if (passed_path[i] == '/' || passed_path[i] == '\\')
{
separator = name[i];
if (strlen(path) > 0)
separator = passed_path[i];
if (strlen(path) > 1)
{
// Append the separator
pos = strlen(path);
path[pos] = separator;
path[pos + 1] = '\0';
}
strcat(path, read_since_last_separator);
read_since_last_separator[0] = '\0';
// Append everything read since last separator
if (strlen(read_since_last_separator) > 0)
{
strcat(path, read_since_last_separator);
read_since_last_separator[0] = '\0';
}
}
else {
// Add to the temp string until we reach the next separator
pos = strlen(read_since_last_separator);
read_since_last_separator[pos] = name[i];
read_since_last_separator[pos] = passed_path[i];
read_since_last_separator[pos + 1] = '\0';
}
}
// Return a pointer to the result
char *result = malloc(sizeof(path));
if (result == NULL)
return NULL;
strcpy(result, path);
return result;
}
\ No newline at end of file
......@@ -4,6 +4,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef _WIN32
#include <limits.h>
#include <errno.h>
#endif
#define ARGS_False 0
#define ARGS_True 1
......@@ -36,4 +41,8 @@ date_t args_parse_date(char *date);
char* args_get_directory_of_executable(char *name);
#ifndef PATH_MAX
#define PATH_MAX 1000
#endif
#endif
\ No newline at end of file
......@@ -5,6 +5,9 @@
#include "logger.h"
#include "args/args.h"
#include "string_literals.h"
#ifndef _WIN32
#include <limits.h>
#endif
static TIMESLIME_STATUS_t status;
......@@ -18,12 +21,14 @@ static void display_help(void);
*/
int main(int argc, char *argv[])
{
log_dull("==== Time Slime ====\n")
// Parse command line arguments
args_t parsed_args;
parsed_args = args_parse(argc, argv);
if (parsed_args.help)
{
display_help();
......@@ -31,35 +36,36 @@ int main(int argc, char *argv[])
else {
// Initialize the TimeSlime library with path for database file
char *base_folder = args_get_directory_of_executable(argv[0]);
if (base_folder == NULL)
{
printf("Unknown fatal error\n");
return 0;
}
status = TimeSlime_Initialize(base_folder);
if (status != TIMESLIME_OK)
{
printf("An error occured: %s\n", TimeSlime_StatusCode(status));
printf("An error occured: %d => %s\n", status, TimeSlime_StatusCode(status));
return -1;
}
if (strcmp(parsed_args.action, ADD_ACTION) == 0)
if (parsed_args.action != NULL && strcmp(parsed_args.action, ADD_ACTION) == 0)
perform_add_action(parsed_args);
else if (strcmp(parsed_args.action, CLOCK_ACTION) == 0)
else if (parsed_args.action != NULL && strcmp(parsed_args.action, CLOCK_ACTION) == 0)
perform_clock_action(parsed_args);
else if (strcmp(parsed_args.action, REPORT_ACTION) == 0)
else if (parsed_args.action != NULL && strcmp(parsed_args.action, REPORT_ACTION) == 0)
perform_report_action(parsed_args);
if (status != TIMESLIME_OK)
{
printf("Error: %s\n", TimeSlime_StatusCode(status));
}
TimeSlime_Close();
free(base_folder);
base_folder = NULL;
}
return 0;
}
......@@ -148,8 +154,9 @@ static void perform_report_action(args_t args)
if (args.modifier2 == NULL)
{
log_error("'report' action needs another parameter, the end date");
return;
args.modifier2 = TODAY;
//log_error("'report' action needs another parameter, the end date");
//return;
}
date_t startDate = args_parse_date(args.modifier1);
......@@ -161,19 +168,22 @@ static void perform_report_action(args_t args)
return;
// Verify that dates are in the correct order
if (
(endDate.month < startDate.month && endDate.year == startDate.year) || // Same year, but earlier month
(endDate.day < startDate.day && endDate.year == startDate.year && endDate.month == startDate.month) || // Same month and year, but earlier day
(endDate.year < startDate.year) // Earlier year
)
if (strcmp(startDate.str, TODAY) != 0 && strcmp(endDate.str, TODAY) != 0)
{
log_error("Dates in wrong order");
return;
if (
(endDate.month < startDate.month && endDate.year == startDate.year) || // Same year, but earlier month
(endDate.day < startDate.day && endDate.year == startDate.year && endDate.month == startDate.month) || // Same month and year, but earlier day
(endDate.year < startDate.year) // Earlier year
)
{
log_error("Dates in wrong order");
return;
}
}
TIMESLIME_REPORT_t *report;
TIMESLIME_DATE_t start = { startDate.year, startDate.month, startDate.day };
TIMESLIME_DATE_t end = { endDate.year, endDate.month, endDate.day };
TIMESLIME_REPORT_t *report;
status = TimeSlime_GetReport(start, end, &report);
log_dull("Time Slime report for %s to %s:", startDate.str, endDate.str);
......
......@@ -59,7 +59,6 @@ TIMESLIME_STATUS_t TimeSlime_Initialize(char directory_for_database[])
return TIMESLIME_UNKOWN_ERROR;
sprintf(database_file_path, "%s%s%s", directory_for_database, TIMESLIME_FILE_PATH_SEPARATOR, TIMESLIME_DATABASE_FILE_NAME); // Append the file name
// Create database if it doesn't exist
int rc;
rc = sqlite3_open(database_file_path, &db);
......@@ -78,7 +77,6 @@ TIMESLIME_STATUS_t TimeSlime_Initialize(char directory_for_database[])
for (i = 0; i < result_array_size; i++)
database_results[i] = NULL;
return _TimeSlime_CreateTables();
}
......@@ -141,18 +139,9 @@ TIMESLIME_STATUS_t TimeSlime_AddHours(float hours, TIMESLIME_DATE_t date)
strcpy(entry.ClockInTime, "NULL");
strcpy(entry.ClockOutTime, "NULL");
if ((date.year == 0) || (date.month == 0) || (date.day == 0))
{
// Use current database date
strcpy(entry.HoursAddedDate, "DATE('now', 'localtime')");
}
else
{
// Use user-specified date
char *dateStr = _TimeSlime_Date2Str(date);
strcpy(entry.HoursAddedDate, dateStr);
free(dateStr);
}
char *dateStr = _TimeSlime_Date2Str(date);
strcpy(entry.HoursAddedDate, dateStr);
free(dateStr);
return _TimeSlime_InsertEntry(&entry);
}
......@@ -182,18 +171,9 @@ TIMESLIME_STATUS_t TimeSlime_ClockIn(TIMESLIME_DATETIME_t time)
strcpy(entry.HoursAddedDate, "NULL");
strcpy(entry.ClockOutTime, "NULL");
if ((time.year == 0) || (time.month == 0) || (time.day == 0) || (time.hour == 0) || (time.minute == 0))
{
// Use current database date
strcpy(entry.ClockInTime, "DATETIME('now', 'localtime')");
}
else
{
// Use user-specified date
char *timeStr = _TimeSlime_Time2Str(time);
strcpy(entry.ClockInTime, timeStr);
free(timeStr);
}
char *timeStr = _TimeSlime_Time2Str(time);
strcpy(entry.ClockInTime, timeStr);
free(timeStr);
return _TimeSlime_InsertEntry(&entry);
}
......@@ -219,22 +199,9 @@ TIMESLIME_STATUS_t TimeSlime_ClockOut(TIMESLIME_DATETIME_t time)
int id = number_of_results - 1; // Last row item ID
// Prep for update
char tmp[TIMESLIME_DATETIME_STR_LENGTH];
strcpy(tmp, database_results[id]->ClockInTime);
sprintf(database_results[id]->ClockInTime, "strftime('%s')", tmp);
if ((time.year == 0) || (time.month == 0) || (time.day == 0) || (time.hour == 0) || (time.minute == 0))
{
// Use current database date
strcpy(database_results[id]->ClockOutTime, "DATETIME('now', 'localtime')");
}
else
{
// Use user-specified date
char *timeStr = _TimeSlime_Time2Str(time);
sprintf(database_results[id]->ClockOutTime, "strftime('%s')", timeStr);
free(timeStr);
}
char *timeStr = _TimeSlime_Time2Str(time);
strcpy(database_results[id]->ClockOutTime, timeStr);
free(timeStr);
return _TimeSlime_UpdateEntry(database_results[id]);
}
......@@ -270,7 +237,7 @@ TIMESLIME_STATUS_t TimeSlime_GetReport(TIMESLIME_DATE_t start, TIMESLIME_DATE_t
sprintf(sql, "SELECT " \
"ID, HoursAdded, HoursAddedDate, ClockInTime, ClockOutTime, " \
"SUM(case when HoursAdded <> 0.0 then HoursAdded else ((JULIANDAY(ClockOutTime) - JULIANDAY(ClockInTime)) * 24) end) AS TotalHours, " \
"case when HoursAddedDate IS NOT NULL then date(HoursAddedDate) else date(ClockInTime) end AS TimeSheetDate " \
"case when HoursAddedDate IS NOT NULL then DATE(HoursAddedDate) else DATE(ClockInTime) end AS TimeSheetDate " \
"FROM TimeSheet " \
"WHERE (%s) AND (TimeSheetDate >= %s AND TimeSheetDate <= %s) " \
"GROUP BY TimeSheetDate " \
......@@ -506,10 +473,10 @@ static TIMESLIME_STATUS_t _TimeSlime_VerifyTimestamp(TIMESLIME_DATETIME_t time)
if (dateResult != TIMESLIME_OK)
return dateResult;
if (time.hour < 0 || time.hour > 24)
if (time.hour < -1 || time.hour > 24)
return TIMESLIME_INVALID_HOUR;
if (time.minute < 0 || time.minute > 60)
if (time.minute < -1 || time.minute > 60)
return TIMESLIME_INVALID_MINUTE;
return TIMESLIME_OK;
......@@ -534,14 +501,19 @@ static TIMESLIME_STATUS_t _TimeSlime_VerifyDate(TIMESLIME_DATE_t date)
static char* _TimeSlime_Time2Str(TIMESLIME_DATETIME_t time)
{
char *result = (char*)malloc(TIMESLIME_DATETIME_STR_LENGTH * sizeof(char));
sprintf(result, "datetime('%04d-%02d-%02d %02d:%02d:0')", time.year, time.month, time.day, time.hour, time.minute);
if (_TIMESLIME_IS_TIME_NOW(time))
strcpy(result, "DATETIME('now', 'localtime')");
else
sprintf(result, "DATETIME('%04d-%02d-%02d %02d:%02d:0')", time.year, time.month, time.day, time.hour, time.minute);
return result;
}
static char* _TimeSlime_Date2Str(TIMESLIME_DATE_t date)
{
char *result = (char*)malloc(TIMESLIME_DATETIME_STR_LENGTH * sizeof(char));
sprintf(result, "date('%04d-%02d-%02d')", date.year, date.month, date.day);
if (_TIMESLIME_IS_DATE_TODAY(date))
strcpy(result, "DATE('now', 'localtime')");
else
sprintf(result, "DATE('%04d-%02d-%02d')", date.year, date.month, date.day);
return result;
}
......@@ -15,7 +15,7 @@
/* Constants */
/* These are used when you want to use the current date */
#define TIMESLIME_DATE_NOW (TIMESLIME_DATE_t){ 0, 0, 0}
#define TIMESLIME_TIME_NOW (TIMESLIME_DATETIME_t){ 0, 0, 0, 0, 0 }
#define TIMESLIME_TIME_NOW (TIMESLIME_DATETIME_t){ 0, 0, 0, -1, -1 }
#ifndef TIMESLIME_DATABASE_FILE_NAME
#define TIMESLIME_DATABASE_FILE_NAME "timeslime.db"
......@@ -128,7 +128,7 @@ char* TimeSlime_StatusCode(TIMESLIME_STATUS_t status);
#ifdef TIMESLIME_VERSION
#undef TIMESLIME_VERSION
#endif
#define TIMESLIME_VERSION 0.8
#define TIMESLIME_VERSION 0.9
#ifdef TIMESLIME_VERSION_STR
#undef TIMESLIME_VERSION_STR
......@@ -143,4 +143,8 @@ char* TimeSlime_StatusCode(TIMESLIME_STATUS_t status);
#endif
#endif
/* Date helper functions */
#define _TIMESLIME_IS_DATE_TODAY(date) (date.year == 0 && date.month == 0 && date.day == 0)
#define _TIMESLIME_IS_TIME_NOW(time) (time.year == 0 && time.month == 0 && time.day == 0 && time.hour == -1 && time.minute == -1)
#endif
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment