aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordam <dam@gudinoff>2023-02-17 16:52:35 +0000
committerdam <dam@gudinoff>2023-02-17 16:52:35 +0000
commitd4d373de28e94e78e44a4f849dbae4d70f48eef9 (patch)
tree6364bf0c4de98d8b649bbc2b8706c01a2017e5d2
parent0b0559e3750c0cc0662640f293cfa7c1f8d0af17 (diff)
downloadtask-time-tracker-d4d373de28e94e78e44a4f849dbae4d70f48eef9.tar.zst
task-time-tracker-d4d373de28e94e78e44a4f849dbae4d70f48eef9.zip
Prototypes for store and load database.
-rw-r--r--ttt.jai187
1 files changed, 176 insertions, 11 deletions
diff --git a/ttt.jai b/ttt.jai
index 1eaf8e1..585d7af 100644
--- a/ttt.jai
+++ b/ttt.jai
@@ -32,7 +32,7 @@ TASK_NAME_BYTES :: #run TASK_NAME_LENGTH+1; // TODO Get rid of this!
FIRST_DAY_OF_WEEK :: 1; // (0-6, Sunday = 0).
NUM_WEEK_DAYS :: 7; // Just to be more clear about what we're looping about.
-APP_FOLDER_NAME :: ".task_time_tracker";
+APP_FOLDER_NAME :: ".task_time_tracker_v2"; // TODO Using _v2 to avoid erasing my work data.
DB_FILE_NAME :: "database.bin";
AR_FILE_NAME :: "archive.csv";
@@ -43,22 +43,26 @@ SECONDS_IN_DAY :: cast(s64)24*SECONDS_IN_HOUR;
SECONDS_IN_YEAR :: cast(s64)365*SECONDS_IN_DAY;
MAX_DATABASE_TASKS :: S64_MAX;
-Task :: struct {
+OldTask :: struct {
times : [NUM_WEEK_DAYS] s64;
name : [TASK_NAME_BYTES] u8; // TODO Start using strings.
}
+Task :: struct {
+ times : [NUM_WEEK_DAYS] s64;
+ name : string~s8;
+ name_data : [62]u8;
+ name.data = cast(*~s8 u8) (0x80 ^ 0x01); // *name_data[0];
+}
+
Database :: struct {
active_task : *~s64 Task = null;
selected_task : *~s64 Task = null;
- tasks : [..] Task;
modified_on : s64;
total_times : [NUM_WEEK_DAYS] s64;
-// size_t count; // Will always be equal or less than capacity. TODO Will this be necessary?
+ tasks : [..] Task;
}
-
-
// const char DB_FILE_SIGN[] = DB_FILE_SIGN_STR;
// const size_t DB_FILE_SIGN_LENGTH = sizeof(DB_FILE_SIGN_STR)-1;
// const size_t SIZEOF_TASK_ST = sizeof(task_st);
@@ -1226,13 +1230,174 @@ main :: () {
app_directory = join(home_path, "/", APP_FOLDER_NAME);
db_file_path = join(app_directory, "/", DB_FILE_NAME);
ar_file_path = join(app_directory, "/", AR_FILE_NAME);
+ }
+
+
+ { // Load database prototype
+
+/*
+typedef struct {
+ task_st *tasks;
+ size_t count; // Will always be equal or less than capacity.
+ size_t capacity; // Will always be equal or less than PTRDIFF_MAX (see MAX_DATABASE_TASKS).
+ ptrdiff_t active_task; // Will always be less than capacity/count.
+ ptrdiff_t selected_task; // Will always be less than capacity/count.
+ int64_t modified_on;
+ int64_t total_times[NUM_WEEK_DAYS];
+} database_st;
+*/
+/*
+Database :: struct {
+ active_task : *~s64 Task = null;
+ selected_task : *~s64 Task = null;
+ modified_on : s64;
+ total_times : [NUM_WEEK_DAYS] s64;
+ tasks : [..] Task;
+}
+*/
+
+ db : Database;
+
+ // I'm having some troubles with the relative pointers:
+ // - array_add uses = to copy the pointers and I lose their values.
+ // - when printing the database after loading from file I'm getting a segmentation fault.
+ // also... the array_add
+ // TODO WIP
+
+ //load_database(*db, db_file_path);
+
+ task : Task;
+ memcpy(task.name.data, "bazinga".data, 7);
+ task.name.count = 7;
+ print(">>>'%'\n", task.name);
+ print("###%\n\n", task);
+
+ add_task(*db, *task);
+ store_database(db, db_file_path);
+
+ //array_add(*db.tasks, task);
+ //memcpy(*db.tasks[0], *task, size_of(Task));
+
+ //print("www\n");
+ print("loaded: %\n", db);
+
+
+
+ add_task :: (db: *Database, task: *Task) {
+ idx := db.tasks.count;
+ maybe_grow(*db.tasks);
+ db.tasks.count += 1;
+ memcpy(*db.tasks[idx], task, size_of(Task));
+ }
+
- // TODO DEBUG
- print_owner_allocator("home_path", home_path.data);
- print_owner_allocator("app_directory", app_directory.data);
- print_owner_allocator("db_file_path", db_file_path.data);
- print_owner_allocator("ar_file_path", ar_file_path.data);
+ // Stores data from database into binary file.
+ // Returns success.
+ store_database :: (db: Database, path: string) -> success: bool {
+ //assert(db != null, "Parameter 'db' is null.");
+ assert(xx path, "Parameter 'path' is empty.");
+
+ // Open file.
+ file, open_success := file_open(path, for_writing = true); // log_errors: bool = true
+ if open_success == false {
+ print_error("Failed to open file '%' while storing database: ERROR_FROM_LOG", path); // TODO Get error from logger ?!
+ return false;
+ }
+
+ file_write(*file, DB_FILE_SIGN_STR);
+ file_write(*file, *db, size_of(Database));
+ //fwrite(DB_FILE_SIGN, SIZEOF_CHAR, DB_FILE_SIGN_LENGTH, file);
+ //fwrite(db, SIZEOF_DATABASE_ST, 1, file);
+ //fwrite(db->tasks, SIZEOF_TASK_ST, db->count, file);
+
+ file_close(*file);
+ return true;
+ }
+
+ // Loads data from binary file into database.
+ // Returns success.
+ load_database :: (db: *Database, path: string) -> success: bool {
+ assert(db != null, "Parameter 'db' is null.");
+ assert(xx path, "Parameter 'path' is empty.");
+
+ // Open file.
+ file, open_success := file_open(path); // log_errors: bool = true
+ if open_success == false {
+ print_error("Failed to open file '%' while loading database: ERROR_FROM_LOG", path); // TODO Get error from logger ?!
+ return false;
+ }
+
+ // Validate file signature.
+ file_signature: [DB_FILE_SIGN_STR.count] u8;
+ read_success := file_read(file, *file_signature, DB_FILE_SIGN_STR.count);
+ if read_success == false print_error("Failed to read file signature from '%'.", path);
+ if cast(string)file_signature != DB_FILE_SIGN_STR {
+ print_error("Invalid file signature.");
+ file_close(*file);
+ return false;
+ }
+
+ // Read database structure.
+
+ read_success = file_read(file, db, size_of(Database));
+ //if read_success == false print_error("Failed to read database info from '%'.", path);
+
+
+ //file_open :: (name: string, for_writing := false, keep_existing_content := false, log_errors := true) -> File, bool
+ //file_read :: (f: File, vdata: *void, bytes_to_read: s64) -> (success: bool, total_read: s64)
+
+ return true;
+ }
+
+ // Loads data from binary file into database.
+ // Returns success.
+ /*
+ load_database :: (
+
+
+ bool load_database(database_st *db, const char *path) {
+ assert(db != NULL);
+ assert(path != NULL);
+
+ // Open file.
+ FILE *file = fopen(path, "rb");
+ if (file == NULL) {
+ print_error("Failed to open file '%s' while loading database: %s.", path, strerror(errno));
+ return false;
+ }
+
+ // Validate file signature.
+ char file_signature[DB_FILE_SIGN_LENGTH];
+ fread(&file_signature, SIZEOF_CHAR, DB_FILE_SIGN_LENGTH, file);
+ if (strncmp(file_signature, DB_FILE_SIGN, DB_FILE_SIGN_LENGTH) != 0) {
+ print_error("Invalid file signature.");
+ fclose(file);
+ return false;
+ }
+
+ // Read database structure.
+ fread(db, SIZEOF_DATABASE_ST, 1, file);
+
+ // Reserve database capacity for tasks.
+ size_t capacity_bytes = db->capacity * SIZEOF_TASK_ST;
+ db->tasks = malloc(capacity_bytes);
+ if (db->tasks == NULL && capacity_bytes > 0) {
+ print_error("Failed to allocate memory while loading database: %s.", strerror(errno));
+ return false;
+ }
+
+ // Read database tasks.
+ fread(db->tasks, SIZEOF_TASK_ST, db->count, file);
+
+ // Make sure we are reading all the file.
+ assert(fgetc(file) == EOF);
+
+ fclose(file);
+ return true;
+ }
+ */
}
+
return; // TODO DEBUG
/*