From 0976d923bf1f13dcba9628efef7e08484b5dc82e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C5=99=C3=ADza?= Date: Tue, 24 Mar 2020 17:29:11 +0100 Subject: [PATCH 01/17] Move library files around to groups that belong together (lib) TODO: make it build on Windows and macOS --- src/CMakeLists.txt | 38 ++++++++++++++------------ src/analytics.cc | 4 +-- src/analytics.h | 5 ++-- src/batch_update_result.cc | 2 +- src/context.cc | 23 ++++++++-------- src/context.h | 6 ++-- src/{ => database}/database.cc | 20 +++++++------- src/{ => database}/database.h | 4 +-- src/{ => database}/migrations.cc | 2 +- src/{ => database}/migrations.h | 0 src/feedback.cc | 2 +- src/gui.cc | 14 +++++----- src/gui.h | 2 +- src/https_client.cc | 2 +- src/idle.cc | 4 +-- src/idle.h | 4 +-- src/{ => model}/autotracker.cc | 0 src/{ => model}/autotracker.h | 0 src/{ => model}/base_model.cc | 4 +-- src/{ => model}/base_model.h | 0 src/{ => model}/client.cc | 2 +- src/{ => model}/client.h | 0 src/{ => model}/obm_action.cc | 2 +- src/{ => model}/obm_action.h | 0 src/{ => model}/project.cc | 2 +- src/{ => model}/project.h | 0 src/{ => model}/settings.cc | 2 +- src/{ => model}/settings.h | 0 src/{ => model}/tag.cc | 0 src/{ => model}/tag.h | 0 src/{ => model}/task.cc | 0 src/{ => model}/task.h | 0 src/{ => model}/time_entry.cc | 2 +- src/{ => model}/time_entry.h | 2 +- src/{ => model}/timeline_event.cc | 0 src/{ => model}/timeline_event.h | 2 +- src/{ => model}/user.cc | 2 +- src/{ => model}/user.h | 0 src/{ => model}/workspace.cc | 2 +- src/{ => model}/workspace.h | 0 src/related_data.cc | 20 +++++++------- src/test/app_test.cc | 26 +++++++++--------- src/test/toggl_api_test.cc | 6 ++-- src/timeline_notifications.h | 7 ++--- src/timeline_uploader.cc | 2 +- src/timeline_uploader.h | 6 ++-- src/toggl_api.cc | 12 ++++---- src/toggl_api_private.cc | 12 ++++---- src/toggl_api_private.h | 4 +-- src/{ => util}/custom_error_handler.cc | 0 src/{ => util}/custom_error_handler.h | 0 src/{ => util}/formatter.cc | 10 +++---- src/{ => util}/formatter.h | 0 src/{ => util}/random.cc | 0 src/{ => util}/random.h | 0 src/{ => util}/rectangle.cc | 0 src/{ => util}/rectangle.h | 0 src/websocket_client.cc | 2 +- 58 files changed, 132 insertions(+), 129 deletions(-) rename src/{ => database}/database.cc (99%) rename src/{ => database}/database.h (99%) rename src/{ => database}/migrations.cc (99%) rename src/{ => database}/migrations.h (100%) rename src/{ => model}/autotracker.cc (100%) rename src/{ => model}/autotracker.h (100%) rename src/{ => model}/base_model.cc (99%) rename src/{ => model}/base_model.h (100%) rename src/{ => model}/client.cc (98%) rename src/{ => model}/client.h (100%) rename src/{ => model}/obm_action.cc (98%) rename src/{ => model}/obm_action.h (100%) rename src/{ => model}/project.cc (99%) rename src/{ => model}/project.h (100%) rename src/{ => model}/settings.cc (99%) rename src/{ => model}/settings.h (100%) rename src/{ => model}/tag.cc (100%) rename src/{ => model}/tag.h (100%) rename src/{ => model}/task.cc (100%) rename src/{ => model}/task.h (100%) rename src/{ => model}/time_entry.cc (99%) rename src/{ => model}/time_entry.h (99%) rename src/{ => model}/timeline_event.cc (100%) rename src/{ => model}/timeline_event.h (98%) rename src/{ => model}/user.cc (99%) rename src/{ => model}/user.h (100%) rename src/{ => model}/workspace.cc (98%) rename src/{ => model}/workspace.h (100%) rename src/{ => util}/custom_error_handler.cc (100%) rename src/{ => util}/custom_error_handler.h (100%) rename src/{ => util}/formatter.cc (99%) rename src/{ => util}/formatter.h (100%) rename src/{ => util}/random.cc (100%) rename src/{ => util}/random.h (100%) rename src/{ => util}/rectangle.cc (100%) rename src/{ => util}/rectangle.h (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 23f8228afe..c3ec272917 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -35,21 +35,34 @@ include_directories( set(LIBRARY_SOURCE_FILES util/logger.cc util/memory.cc + util/custom_error_handler.cc + util/rectangle.cc + util/random.cc + util/formatter.cc + + model/autotracker.cc + model/base_model.cc + model/client.cc + model/obm_action.cc + model/project.cc + model/settings.cc + model/tag.cc + model/task.cc + model/time_entry.cc + model/timeline_event.cc + model/user.cc + model/workspace.cc + + database/database.cc + database/migrations.cc - base_model.cc batch_update_result.cc - client.cc idle.cc analytics.cc help_article.cc - autotracker.cc urls.cc - migrations.cc context.cc - custom_error_handler.cc - database.cc feedback.cc - formatter.cc get_focused_window_linux.cc error.cc gui.cc @@ -58,23 +71,12 @@ set(LIBRARY_SOURCE_FILES toggl_api.cc toggl_api_private.cc model_change.cc - obm_action.cc platforminfo.cc - project.cc proxy.cc - random.cc - rectangle.cc related_data.cc - settings.cc - tag.cc - task.cc - timeline_event.cc - time_entry.cc timeline_uploader.cc - user.cc websocket_client.cc window_change_recorder.cc - workspace.cc ) # Set up compilation targets diff --git a/src/analytics.cc b/src/analytics.cc index f42b4db2e3..d989d64575 100644 --- a/src/analytics.cc +++ b/src/analytics.cc @@ -14,10 +14,10 @@ #include "const.h" #include "https_client.h" #include "platforminfo.h" -#include "settings.h" #include "urls.h" -#include "user.h" #include "util/logger.h" +#include "model/settings.h" +#include "model/user.h" namespace toggl { diff --git a/src/analytics.h b/src/analytics.h index 99f1aa3e22..0c0a66593e 100644 --- a/src/analytics.h +++ b/src/analytics.h @@ -8,9 +8,10 @@ #include #include #include + #include "proxy.h" -#include "settings.h" -#include "rectangle.h" +#include "util/rectangle.h" +#include "model/settings.h" namespace toggl { diff --git a/src/batch_update_result.cc b/src/batch_update_result.cc index 9cb8f0e6c0..79097c10da 100644 --- a/src/batch_update_result.cc +++ b/src/batch_update_result.cc @@ -5,7 +5,7 @@ #include #include -#include "base_model.h" +#include "model/base_model.h" namespace toggl { diff --git a/src/context.cc b/src/context.cc index fe30bba8ef..776397f79a 100644 --- a/src/context.cc +++ b/src/context.cc @@ -13,23 +13,24 @@ #include // NOLINT -#include "autotracker.h" -#include "client.h" #include "const.h" -#include "database.h" #include "error.h" -#include "formatter.h" #include "https_client.h" -#include "obm_action.h" -#include "project.h" -#include "random.h" -#include "settings.h" -#include "task.h" -#include "time_entry.h" #include "timeline_uploader.h" #include "urls.h" #include "window_change_recorder.h" -#include "workspace.h" + +#include "util/formatter.h" +#include "util/random.h" +#include "database/database.h" +#include "model/autotracker.h" +#include "model/client.h" +#include "model/obm_action.h" +#include "model/project.h" +#include "model/settings.h" +#include "model/task.h" +#include "model/time_entry.h" +#include "model/workspace.h" #include #include diff --git a/src/context.h b/src/context.h index dfb6ddfbe3..048cc050e7 100644 --- a/src/context.h +++ b/src/context.h @@ -11,17 +11,17 @@ #include // NOLINT #include "analytics.h" -#include "custom_error_handler.h" #include "feedback.h" #include "gui.h" #include "help_article.h" #include "idle.h" -#include "util/logger.h" #include "model_change.h" -#include "timeline_event.h" #include "timeline_notifications.h" #include "types.h" #include "websocket_client.h" +#include "util/custom_error_handler.h" +#include "util/logger.h" +#include "model/timeline_event.h" #include #include diff --git a/src/database.cc b/src/database/database.cc similarity index 99% rename from src/database.cc rename to src/database/database.cc index 6e41b850ec..5ada990621 100644 --- a/src/database.cc +++ b/src/database/database.cc @@ -8,19 +8,19 @@ #include #include -#include "autotracker.h" -#include "client.h" +#include "model/autotracker.h" +#include "model/client.h" +#include "model/obm_action.h" +#include "model/project.h" +#include "model/settings.h" +#include "model/tag.h" +#include "model/task.h" +#include "model/time_entry.h" +#include "model/user.h" +#include "model/workspace.h" #include "const.h" #include "migrations.h" -#include "obm_action.h" -#include "project.h" #include "proxy.h" -#include "settings.h" -#include "tag.h" -#include "task.h" -#include "time_entry.h" -#include "user.h" -#include "workspace.h" #include #include diff --git a/src/database.h b/src/database/database.h similarity index 99% rename from src/database.h rename to src/database/database.h index b1a2cae945..7360596db9 100644 --- a/src/database.h +++ b/src/database/database.h @@ -14,10 +14,10 @@ #include +#include "util/logger.h" +#include "model/timeline_event.h" #include "model_change.h" -#include "timeline_event.h" #include "types.h" -#include "util/logger.h" namespace Poco { namespace Data { diff --git a/src/migrations.cc b/src/database/migrations.cc similarity index 99% rename from src/migrations.cc rename to src/database/migrations.cc index 9827ac0aa6..a02cc5dff9 100644 --- a/src/migrations.cc +++ b/src/database/migrations.cc @@ -4,7 +4,7 @@ #include "const.h" #include "database.h" -#include "random.h" +#include "util/random.h" namespace toggl { diff --git a/src/migrations.h b/src/database/migrations.h similarity index 100% rename from src/migrations.h rename to src/database/migrations.h diff --git a/src/feedback.cc b/src/feedback.cc index 5d1ff4217c..45f9f6765b 100644 --- a/src/feedback.cc +++ b/src/feedback.cc @@ -4,8 +4,8 @@ #include -#include "formatter.h" #include "https_client.h" +#include "util/formatter.h" #include diff --git a/src/gui.cc b/src/gui.cc index 04e51c3141..5e1b4eff26 100644 --- a/src/gui.cc +++ b/src/gui.cc @@ -6,16 +6,16 @@ #include #include -#include "client.h" #include "const.h" #include "error.h" -#include "formatter.h" -#include "project.h" #include "related_data.h" -#include "task.h" -#include "time_entry.h" -#include "user.h" -#include "workspace.h" +#include "util/formatter.h" +#include "model/client.h" +#include "model/project.h" +#include "model/task.h" +#include "model/time_entry.h" +#include "model/user.h" +#include "model/workspace.h" #include diff --git a/src/gui.h b/src/gui.h index fc2b7f6df1..f764ce35a4 100644 --- a/src/gui.h +++ b/src/gui.h @@ -10,11 +10,11 @@ #include "help_article.h" #include "https_client.h" #include "proxy.h" -#include "settings.h" #include "toggl_api.h" #include "toggl_api_private.h" #include "types.h" #include "util/logger.h" +#include "model/settings.h" #include diff --git a/src/https_client.cc b/src/https_client.cc index c9f8efb88a..2f68db1ad6 100644 --- a/src/https_client.cc +++ b/src/https_client.cc @@ -7,10 +7,10 @@ #include #include -#include "formatter.h" #include "netconf.h" #include "urls.h" #include "toggl_api.h" +#include "util/formatter.h" #include #include diff --git a/src/idle.cc b/src/idle.cc index 0ffda11391..9c80b9fb2a 100644 --- a/src/idle.cc +++ b/src/idle.cc @@ -8,9 +8,9 @@ #include "idle.h" -#include "formatter.h" #include "gui.h" -#include "time_entry.h" +#include "util/formatter.h" +#include "model/time_entry.h" namespace toggl { diff --git a/src/idle.h b/src/idle.h index f7daec2803..8d87b58433 100644 --- a/src/idle.h +++ b/src/idle.h @@ -5,9 +5,9 @@ #include -#include "settings.h" -#include "user.h" #include "util/logger.h" +#include "model/settings.h" +#include "model/user.h" #include diff --git a/src/autotracker.cc b/src/model/autotracker.cc similarity index 100% rename from src/autotracker.cc rename to src/model/autotracker.cc diff --git a/src/autotracker.h b/src/model/autotracker.h similarity index 100% rename from src/autotracker.h rename to src/model/autotracker.h diff --git a/src/base_model.cc b/src/model/base_model.cc similarity index 99% rename from src/base_model.cc rename to src/model/base_model.cc index 904ae055bd..0db2472ef0 100644 --- a/src/base_model.cc +++ b/src/model/base_model.cc @@ -5,11 +5,11 @@ #include #include "batch_update_result.h" -#include "database.h" -#include "formatter.h" #include "model_change.h" #include "related_data.h" #include "user.h" +#include "util/formatter.h" +#include "database/database.h" #include #include diff --git a/src/base_model.h b/src/model/base_model.h similarity index 100% rename from src/base_model.h rename to src/model/base_model.h diff --git a/src/client.cc b/src/model/client.cc similarity index 98% rename from src/client.cc rename to src/model/client.cc index 22b1779664..b5b6839d3b 100644 --- a/src/client.cc +++ b/src/model/client.cc @@ -5,7 +5,7 @@ #include #include -#include "formatter.h" +#include "util/formatter.h" namespace toggl { diff --git a/src/client.h b/src/model/client.h similarity index 100% rename from src/client.h rename to src/model/client.h diff --git a/src/obm_action.cc b/src/model/obm_action.cc similarity index 98% rename from src/obm_action.cc rename to src/model/obm_action.cc index 27e7d642cd..1f0d0767a1 100644 --- a/src/obm_action.cc +++ b/src/model/obm_action.cc @@ -4,7 +4,7 @@ #include -#include "formatter.h" +#include "util/formatter.h" namespace toggl { diff --git a/src/obm_action.h b/src/model/obm_action.h similarity index 100% rename from src/obm_action.h rename to src/model/obm_action.h diff --git a/src/project.cc b/src/model/project.cc similarity index 99% rename from src/project.cc rename to src/model/project.cc index 80bdbce238..8e0dee0520 100644 --- a/src/project.cc +++ b/src/model/project.cc @@ -9,7 +9,7 @@ #include #include -#include "formatter.h" +#include "util/formatter.h" namespace toggl { diff --git a/src/project.h b/src/model/project.h similarity index 100% rename from src/project.h rename to src/model/project.h diff --git a/src/settings.cc b/src/model/settings.cc similarity index 99% rename from src/settings.cc rename to src/model/settings.cc index 889dd87bb8..e2373f7d38 100644 --- a/src/settings.cc +++ b/src/model/settings.cc @@ -2,7 +2,7 @@ #include "settings.h" -#include "formatter.h" +#include "util/formatter.h" namespace toggl { diff --git a/src/settings.h b/src/model/settings.h similarity index 100% rename from src/settings.h rename to src/model/settings.h diff --git a/src/tag.cc b/src/model/tag.cc similarity index 100% rename from src/tag.cc rename to src/model/tag.cc diff --git a/src/tag.h b/src/model/tag.h similarity index 100% rename from src/tag.h rename to src/model/tag.h diff --git a/src/task.cc b/src/model/task.cc similarity index 100% rename from src/task.cc rename to src/model/task.cc diff --git a/src/task.h b/src/model/task.h similarity index 100% rename from src/task.h rename to src/model/task.h diff --git a/src/time_entry.cc b/src/model/time_entry.cc similarity index 99% rename from src/time_entry.cc rename to src/model/time_entry.cc index 76b522fb1a..734b4b41cc 100644 --- a/src/time_entry.cc +++ b/src/model/time_entry.cc @@ -17,7 +17,7 @@ #include // NOLINT #include "https_client.h" -#include "formatter.h" +#include "util/formatter.h" #include #include diff --git a/src/time_entry.h b/src/model/time_entry.h similarity index 99% rename from src/time_entry.h rename to src/model/time_entry.h index 69ce70701a..2f995458b7 100644 --- a/src/time_entry.h +++ b/src/model/time_entry.h @@ -7,8 +7,8 @@ #include #include "base_model.h" -#include "formatter.h" #include "types.h" +#include "util/formatter.h" #include diff --git a/src/timeline_event.cc b/src/model/timeline_event.cc similarity index 100% rename from src/timeline_event.cc rename to src/model/timeline_event.cc diff --git a/src/timeline_event.h b/src/model/timeline_event.h similarity index 98% rename from src/timeline_event.h rename to src/model/timeline_event.h index 70a5d654b4..4ca8708035 100644 --- a/src/timeline_event.h +++ b/src/model/timeline_event.h @@ -9,7 +9,7 @@ #include #include "base_model.h" -#include "formatter.h" +#include "util/formatter.h" namespace toggl { diff --git a/src/user.cc b/src/model/user.cc similarity index 99% rename from src/user.cc rename to src/model/user.cc index 2385ba88c2..3cf3214000 100644 --- a/src/user.cc +++ b/src/model/user.cc @@ -8,7 +8,6 @@ #include "client.h" #include "const.h" -#include "formatter.h" #include "https_client.h" #include "obm_action.h" #include "project.h" @@ -17,6 +16,7 @@ #include "time_entry.h" #include "timeline_event.h" #include "urls.h" +#include "util/formatter.h" #include #include diff --git a/src/user.h b/src/model/user.h similarity index 100% rename from src/user.h rename to src/model/user.h diff --git a/src/workspace.cc b/src/model/workspace.cc similarity index 98% rename from src/workspace.cc rename to src/model/workspace.cc index 6cedb9416a..dcbbe8c931 100644 --- a/src/workspace.cc +++ b/src/model/workspace.cc @@ -3,7 +3,7 @@ #include "workspace.h" #include -#include "formatter.h" +#include "util/formatter.h" namespace toggl { diff --git a/src/workspace.h b/src/model/workspace.h similarity index 100% rename from src/workspace.h rename to src/model/workspace.h diff --git a/src/related_data.cc b/src/related_data.cc index 247039711a..186288c13c 100644 --- a/src/related_data.cc +++ b/src/related_data.cc @@ -7,17 +7,17 @@ #include -#include "autotracker.h" -#include "formatter.h" -#include "client.h" #include "gui.h" -#include "obm_action.h" -#include "project.h" -#include "tag.h" -#include "task.h" -#include "time_entry.h" -#include "user.h" -#include "workspace.h" +#include "util/formatter.h" +#include "model/autotracker.h" +#include "model/client.h" +#include "model/obm_action.h" +#include "model/project.h" +#include "model/tag.h" +#include "model/task.h" +#include "model/time_entry.h" +#include "model/user.h" +#include "model/workspace.h" namespace toggl { diff --git a/src/test/app_test.cc b/src/test/app_test.cc index 1d73f203b7..e11f17a8d7 100644 --- a/src/test/app_test.cc +++ b/src/test/app_test.cc @@ -4,22 +4,22 @@ #include // NOLINT -#include "./../autotracker.h" -#include "./../client.h" #include "./../const.h" -#include "./../database.h" -#include "./../formatter.h" -#include "./../obm_action.h" -#include "./../project.h" #include "./../proxy.h" -#include "./../settings.h" -#include "./../tag.h" -#include "./../task.h" -#include "./../time_entry.h" -#include "./../timeline_event.h" #include "./../timeline_uploader.h" -#include "./../user.h" -#include "./../workspace.h" +#include "./../util/formatter.h" +#include "./../database/database.h" +#include "./../model/autotracker.h" +#include "./../model/client.h" +#include "./../model/obm_action.h" +#include "./../model/project.h" +#include "./../model/settings.h" +#include "./../model/tag.h" +#include "./../model/task.h" +#include "./../model/time_entry.h" +#include "./../model/timeline_event.h" +#include "./../model/user.h" +#include "./../model/workspace.h" #include "./test_data.h" diff --git a/src/test/toggl_api_test.cc b/src/test/toggl_api_test.cc index 95e1884a01..d55728aa91 100644 --- a/src/test/toggl_api_test.cc +++ b/src/test/toggl_api_test.cc @@ -6,12 +6,12 @@ #include "toggl_api_test.h" #include "./../https_client.h" -#include "./../obm_action.h" #include "./../proxy.h" -#include "./../settings.h" -#include "./../time_entry.h" #include "./../toggl_api.h" #include "./../toggl_api_private.h" +#include "./../model/obm_action.h" +#include "./../model/settings.h" +#include "./../model/time_entry.h" #include "./test_data.h" #include // NOLINT diff --git a/src/timeline_notifications.h b/src/timeline_notifications.h index a8c351f9f5..ae09ec96a6 100644 --- a/src/timeline_notifications.h +++ b/src/timeline_notifications.h @@ -3,15 +3,14 @@ #ifndef SRC_TIMELINE_NOTIFICATIONS_H_ #define SRC_TIMELINE_NOTIFICATIONS_H_ -#include "timeline_event.h" - #include #include -#include "types.h" - #include +#include "types.h" +#include "model/timeline_event.h" + namespace toggl { class TOGGL_INTERNAL_EXPORT TimelineBatch { diff --git a/src/timeline_uploader.cc b/src/timeline_uploader.cc index 816c4d04a4..7082609a46 100644 --- a/src/timeline_uploader.cc +++ b/src/timeline_uploader.cc @@ -5,9 +5,9 @@ #include #include -#include "formatter.h" #include "https_client.h" #include "urls.h" +#include "util/formatter.h" #include #include diff --git a/src/timeline_uploader.h b/src/timeline_uploader.h index 5dc4f76e2f..120280aff9 100644 --- a/src/timeline_uploader.h +++ b/src/timeline_uploader.h @@ -6,12 +6,12 @@ #include #include -#include "timeline_event.h" +#include + #include "timeline_notifications.h" #include "types.h" #include "util/logger.h" - -#include +#include "model/timeline_event.h" namespace toggl { diff --git a/src/toggl_api.cc b/src/toggl_api.cc index e8192ec008..57518ef3f2 100644 --- a/src/toggl_api.cc +++ b/src/toggl_api.cc @@ -9,21 +9,21 @@ #include "toggl_api_lua.h" -#include "client.h" #include "const.h" #include "context.h" -#include "custom_error_handler.h" #include "feedback.h" -#include "formatter.h" #include "https_client.h" -#include "project.h" #include "proxy.h" -#include "time_entry.h" #include "timeline_uploader.h" #include "toggl_api_private.h" -#include "user.h" #include "websocket_client.h" #include "window_change_recorder.h" +#include "util/custom_error_handler.h" +#include "util/formatter.h" +#include "model/client.h" +#include "model/project.h" +#include "model/time_entry.h" +#include "model/user.h" #include #include diff --git a/src/toggl_api_private.cc b/src/toggl_api_private.cc index d8a6c22643..cfdc2bdf73 100644 --- a/src/toggl_api_private.cc +++ b/src/toggl_api_private.cc @@ -4,13 +4,13 @@ #include -#include "client.h" #include "context.h" -#include "formatter.h" -#include "project.h" -#include "time_entry.h" -#include "timeline_event.h" -#include "workspace.h" +#include "util/formatter.h" +#include "model/client.h" +#include "model/project.h" +#include "model/time_entry.h" +#include "model/timeline_event.h" +#include "model/workspace.h" #include diff --git a/src/toggl_api_private.h b/src/toggl_api_private.h index bcc4a7a0d7..1f462af306 100644 --- a/src/toggl_api_private.h +++ b/src/toggl_api_private.h @@ -6,12 +6,12 @@ #include #include -#include "autotracker.h" #include "help_article.h" #include "proxy.h" -#include "settings.h" #include "toggl_api.h" #include "util/logger.h" +#include "model/autotracker.h" +#include "model/settings.h" namespace toggl { class Client; diff --git a/src/custom_error_handler.cc b/src/util/custom_error_handler.cc similarity index 100% rename from src/custom_error_handler.cc rename to src/util/custom_error_handler.cc diff --git a/src/custom_error_handler.h b/src/util/custom_error_handler.h similarity index 100% rename from src/custom_error_handler.h rename to src/util/custom_error_handler.h diff --git a/src/formatter.cc b/src/util/formatter.cc similarity index 99% rename from src/formatter.cc rename to src/util/formatter.cc index aa35220be1..23b954706a 100644 --- a/src/formatter.cc +++ b/src/util/formatter.cc @@ -7,13 +7,13 @@ #include #include -#include "client.h" #include "gui.h" -#include "project.h" -#include "task.h" -#include "time_entry.h" -#include "workspace.h" #include "util/logger.h" +#include "model/client.h" +#include "model/project.h" +#include "model/task.h" +#include "model/time_entry.h" +#include "model/workspace.h" #include #include diff --git a/src/formatter.h b/src/util/formatter.h similarity index 100% rename from src/formatter.h rename to src/util/formatter.h diff --git a/src/random.cc b/src/util/random.cc similarity index 100% rename from src/random.cc rename to src/util/random.cc diff --git a/src/random.h b/src/util/random.h similarity index 100% rename from src/random.h rename to src/util/random.h diff --git a/src/rectangle.cc b/src/util/rectangle.cc similarity index 100% rename from src/rectangle.cc rename to src/util/rectangle.cc diff --git a/src/rectangle.h b/src/util/rectangle.h similarity index 100% rename from src/rectangle.h rename to src/util/rectangle.h diff --git a/src/websocket_client.cc b/src/websocket_client.cc index a0910307ea..a93f5dbb2b 100644 --- a/src/websocket_client.cc +++ b/src/websocket_client.cc @@ -24,8 +24,8 @@ #include "const.h" #include "https_client.h" #include "netconf.h" -#include "random.h" #include "urls.h" +#include "util/random.h" namespace toggl { From b03b43638c73f346cc1f697fc462825bd6d1a4eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C5=99=C3=ADza?= Date: Tue, 24 Mar 2020 17:41:24 +0100 Subject: [PATCH 02/17] Add migrations to add GUID columns to all BaseModel classes (lib) --- src/database/migrations.cc | 66 +++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/src/database/migrations.cc b/src/database/migrations.cc index a02cc5dff9..eb46a7704e 100644 --- a/src/database/migrations.cc +++ b/src/database/migrations.cc @@ -9,7 +9,7 @@ namespace toggl { error Migrations::migrateObmActions() { - return db_->Migrate( + error err = db_->Migrate( "obm_actions", "create table obm_actions(" "local_id integer primary key," @@ -20,6 +20,18 @@ error Migrations::migrateObmActions() { "constraint fk_obm_actions_uid foreign key (uid) " " references users(id) on delete no action on update no action" "); "); + if (err != noError) { + return err; + } + + err = db_->Migrate( + "obm_actions.guid", + "ALTER TABLE obm_actions " + "ADD COLUMN guid VARCHAR;" + "CREATE UNIQUE INDEX id_obm_actions_guid ON obm_actions (uid, guid);"); + if (err != noError) { + return err; + } } error Migrations::migrateObmExperiments() { @@ -62,6 +74,15 @@ error Migrations::migrateObmExperiments() { return err; } + err = db_->Migrate( + "obm_experiments.guid", + "ALTER TABLE obm_experiments " + "ADD COLUMN guid VARCHAR;" + "CREATE UNIQUE INDEX id_obm_experiments_guid ON obm_experiments (uid, guid);"); + if (err != noError) { + return err; + } + return err; } @@ -98,6 +119,15 @@ error Migrations::migrateAutotracker() { return err; } + err = db_->Migrate( + "autotracker_settings.guid", + "ALTER TABLE autotracker_settings " + "ADD COLUMN guid VARCHAR;" + "CREATE UNIQUE INDEX id_autotracker_settings_guid ON autotracker_settings (uid, guid);"); + if (err != noError) { + return err; + } + return noError; } @@ -180,6 +210,15 @@ error Migrations::migrateTasks() { return err; } + err = db_->Migrate( + "tasks.guid", + "ALTER TABLE tasks " + "ADD COLUMN guid VARCHAR;" + "CREATE UNIQUE INDEX id_tasks_guid ON tasks (uid, guid);"); + if (err != noError) { + return err; + } + return noError; } @@ -318,6 +357,15 @@ error Migrations::migrateWorkspaces() { return err; } + err = db_->Migrate( + "workspaces.guid", + "ALTER TABLE workspaces " + "ADD COLUMN guid VARCHAR;" + "CREATE UNIQUE INDEX id_workspaces_guid ON workspaces (uid, guid);"); + if (err != noError) { + return err; + } + return err; } @@ -665,6 +713,14 @@ error Migrations::migrateUsers() { return err; } + err = db_->Migrate( + "users.guid", + "ALTER TABLE users " + "ADD COLUMN guid VARCHAR;"); + if (err != noError) { + return err; + } + return err; } @@ -1313,6 +1369,14 @@ error Migrations::migrateSettings() { return err; } + err = db_->Migrate( + "settings.guid", + "ALTER TABLE settings " + "ADD COLUMN guid VARCHAR;"); + if (err != noError) { + return err; + } + return noError; } From e6756ee2fd9bda5f88c5782995e16663f9df39c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C5=99=C3=ADza?= Date: Tue, 24 Mar 2020 19:23:59 +0100 Subject: [PATCH 03/17] Add a generic BaseModelQuery structure to handle database constructors (lib) --- src/CMakeLists.txt | 2 +- src/model/base_model.cc | 35 ++++++++++++ src/model/base_model.h | 114 +++++++++++++++++++++++++++++++++++++++- src/test/CMakeLists.txt | 6 +-- 4 files changed, 152 insertions(+), 5 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c3ec272917..ba1defce09 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -86,7 +86,7 @@ add_library(TogglDesktopLibrary SHARED ${LIBRARY_SOURCE_FILES}) target_link_libraries(TogglDesktopLibrary PRIVATE ${JSONCPP_LIBRARIES} ${LUA_LIBRARIES} - PocoCrypto PocoDataSQLite PocoNetSSL + PocoData PocoCrypto PocoDataSQLite PocoNetSSL ) install(TARGETS TogglDesktopLibrary DESTINATION lib) diff --git a/src/model/base_model.cc b/src/model/base_model.cc index 0db2472ef0..5c407792b8 100644 --- a/src/model/base_model.cc +++ b/src/model/base_model.cc @@ -282,4 +282,39 @@ void BaseModel::SetUnsynced() { unsynced_ = true; } +std::string BaseModelQuery::ToSelect(const std::string &where) const { + std::ostringstream ss; + /* + * columns + */ + ss << "SELECT "; + bool firstColumn = true; + if (parent_) + printColumns(ss, firstColumn, parent_->columns_); + printColumns(ss, firstColumn, columns_); + /* + * table name + */ + ss << " FROM " << table_; + /* + * join (optional) + */ + for (auto i : join_) + ss << " " << i; + /* + * condition (actual value supplied outside as a reference) + */ + ss << " WHERE " << table_ << "." << where << " = :" << where; + /* + * order (optional) + */ + if (!order_.empty()) { + bool firstOrder = true; // disney ruined star wars :( + ss << " ORDER BY "; + printColumns(ss, firstOrder, order_); + } + ss << ";"; + return ss.str(); +} + } // namespace toggl diff --git a/src/model/base_model.h b/src/model/base_model.h index c96e9365e6..f88d824953 100644 --- a/src/model/base_model.h +++ b/src/model/base_model.h @@ -17,14 +17,102 @@ #include "https_client.h" #include +#include namespace toggl { class ProtectedBase; class BatchUpdateResult; +/** + * @brief The BaseModelQuery struct + * Use to determine how to retrieve data from the database. Each BaseModel class should implement this and + * reference BaseModel::query as the @ref parent_ pointer. + * + * Only the @ref columns_ list will be prepended to the implementation. + * That means, if you do this: + * In BaseModel: Query { "", { "base1", "base2"}, ... + * In Client: { "clients", { "client1", "client2" }, ... + * Then Client query will work with the "clients" table and look for columns "base1", "base2", "client1", "client2" (in this order). + * This is to have things like ID, Local ID and GUID in the base class for all models here in one place + * and to not have to handle their serialization in all child classes separately. + */ +struct BaseModelQuery { + typedef std::function db_load_t; + + struct Binding { + enum Type { + REQUIRED = 0, + OPTIONAL + }; + std::string column; + db_load_t load; + }; + + typedef std::vector Join; + typedef std::string Table; + typedef std::vector Columns; + typedef std::vector OrderBy; + + Table table_ {}; + Columns columns_ {}; + Join join_ {}; + OrderBy order_ {}; + const BaseModelQuery *parent_ { nullptr }; + + /** + * @brief ToSelect + * @param where - which column will be supplied outside as the WHERE condition + * @return string with the completed SELECT query + */ + std::string ToSelect(const std::string &where = "uid") const; + + size_t ColumnCount() const { + return columns_.size(); + } + + /** + * @brief column helper method to retrieve column name from aggregate types (like @ref Binding) + * @param item + * @return column name of the item + */ + static const std::string &column(const std::string &item) { return item; } + static const std::string &column(const Binding &item) { return item.column; } + /** + * @brief writes a list of columns to @ref ss + * Handles case when there's multiple tables and prepends "main" table name to columns without a dot + */ + template + void printColumns(std::ostringstream &ss, bool &first, T &list) const { + for (auto i : list) { + if (!first) + ss << ", "; + first = false; + if (!join_.empty() && column(i).find(".") == std::string::npos) + ss << table_ << "."; + ss << column(i); + } + }; + + template + static Binding Bind(const std::string &column, Value Class::*ptr, Binding::Type required) { + return { + column, + [ptr, required](void *that, Poco::Data::RecordSet &rs, size_t index) { + auto actuallyThat = reinterpret_cast(that); + if (!rs[index].isEmpty() || required) { + (actuallyThat->*ptr) = rs[index].convert(); + return true; + } + return false; + } + }; + } +}; + class TOGGL_INTERNAL_EXPORT BaseModel { - public: + protected: + using Query = BaseModelQuery; BaseModel(ProtectedBase *container) : container_(container) , local_id_(0) @@ -39,7 +127,18 @@ class TOGGL_INTERNAL_EXPORT BaseModel { , validation_error_("") , unsynced_(false) {} + BaseModel(ProtectedBase *container, Poco::Data::RecordSet &rs) + : container_(container) + { + for (size_t i = 0; i < query.ColumnCount(); i++) { + bool result = query.columns_[i].load(this, rs, i); + } + ClearDirty(); + } + + virtual ~BaseModel() {} + public: ProtectedBase *GetContainer(); const ProtectedBase *GetContainer() const; @@ -195,6 +294,19 @@ class TOGGL_INTERNAL_EXPORT BaseModel { // pushed to backend. It only means that some // attempt to push failed somewhere. bool unsynced_; + + inline static const Query query { + Query::Table(), + Query::Columns({ + Query::Bind("local_id", &BaseModel::local_id_, Query::Binding::REQUIRED), + Query::Bind("id", &BaseModel::id_, Query::Binding::OPTIONAL), + Query::Bind("uid", &BaseModel::uid_, Query::Binding::REQUIRED), + Query::Bind("guid", &BaseModel::guid_, Query::Binding::OPTIONAL) + }), + Query::Join(), + Query::OrderBy(), + nullptr + }; }; } // namespace toggl diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 5bd866c459..36cd4c369d 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -17,7 +17,7 @@ target_link_libraries(TogglApiTest PRIVATE TogglDesktopLibrary ${JSONCPP_LIBRARIES} ${LUA_LIBRARIES} - PocoCrypto PocoDataSQLite PocoNetSSL PocoFoundation + PocoData PocoCrypto PocoDataSQLite PocoNetSSL PocoFoundation PocoData gtest_main gtest X11 ) @@ -31,7 +31,7 @@ target_link_libraries(TogglAppTest PRIVATE TogglDesktopLibrary ${JSONCPP_LIBRARIES} ${LUA_LIBRARIES} - PocoCrypto PocoDataSQLite PocoNetSSL PocoFoundation + PocoData PocoCrypto PocoDataSQLite PocoNetSSL PocoFoundation PocoData gtest_main gtest X11 ) @@ -45,7 +45,7 @@ target_link_libraries(TogglMemoryTest PRIVATE TogglDesktopLibrary ${JSONCPP_LIBRARIES} ${LUA_LIBRARIES} - PocoCrypto PocoDataSQLite PocoNetSSL PocoFoundation + PocoData PocoCrypto PocoDataSQLite PocoNetSSL PocoFoundation gtest_main gtest X11 ) From 20a027f1c9046bde759cb7ccd71526fc800fce64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C5=99=C3=ADza?= Date: Tue, 24 Mar 2020 19:42:23 +0100 Subject: [PATCH 04/17] Move current BaseModel class default value constructors to member declarations (lib) The commit message feels like a bunch of gibberish but it really is what it says. --- src/model/autotracker.h | 10 ++--- src/model/base_model.h | 39 +++++++--------- src/model/client.h | 7 ++- src/model/obm_action.h | 23 ++++------ src/model/project.h | 30 +++++-------- src/model/settings.h | 91 +++++++++++++------------------------- src/model/tag.h | 7 ++- src/model/task.h | 13 +++--- src/model/time_entry.h | 40 ++++++----------- src/model/timeline_event.h | 25 ++++------- src/model/user.h | 45 +++++++------------ src/model/workspace.h | 22 ++++----- 12 files changed, 128 insertions(+), 224 deletions(-) diff --git a/src/model/autotracker.h b/src/model/autotracker.h index 239fcfafcb..50ae5ae41b 100644 --- a/src/model/autotracker.h +++ b/src/model/autotracker.h @@ -17,9 +17,7 @@ namespace toggl { class TOGGL_INTERNAL_EXPORT AutotrackerRule : public BaseModel { AutotrackerRule(ProtectedBase *container) : BaseModel(container) - , term_("") - , pid_(0) - , tid_(0) {} + {} public: friend class ProtectedBase; @@ -42,9 +40,9 @@ class TOGGL_INTERNAL_EXPORT AutotrackerRule : public BaseModel { std::string ModelURL() const override; private: - std::string term_; - Poco::UInt64 pid_; - Poco::UInt64 tid_; + std::string term_ { "" }; + Poco::UInt64 pid_ { 0 }; + Poco::UInt64 tid_ { 0 }; }; }; // namespace toggl diff --git a/src/model/base_model.h b/src/model/base_model.h index f88d824953..0115f5e87a 100644 --- a/src/model/base_model.h +++ b/src/model/base_model.h @@ -115,17 +115,7 @@ class TOGGL_INTERNAL_EXPORT BaseModel { using Query = BaseModelQuery; BaseModel(ProtectedBase *container) : container_(container) - , local_id_(0) - , id_(0) - , guid_("") - , ui_modified_at_(0) - , uid_(0) - , dirty_(false) - , deleted_at_(0) - , is_marked_as_deleted_on_server_(false) - , updated_at_(0) - , validation_error_("") - , unsynced_(false) {} + {} BaseModel(ProtectedBase *container, Poco::Data::RecordSet &rs) : container_(container) @@ -272,29 +262,32 @@ class TOGGL_INTERNAL_EXPORT BaseModel { std::string batchUpdateRelativeURL() const; std::string batchUpdateMethod() const; - ProtectedBase *container_; + ProtectedBase *container_ { nullptr }; - Poco::Int64 local_id_; - Poco::UInt64 id_; - guid guid_; - Poco::Int64 ui_modified_at_; - Poco::UInt64 uid_; - bool dirty_; - Poco::Int64 deleted_at_; - bool is_marked_as_deleted_on_server_; - Poco::Int64 updated_at_; + Poco::Int64 local_id_ { 0 }; + Poco::UInt64 id_ { 0 }; + Poco::Int64 ui_modified_at_ { 0 }; + Poco::UInt64 uid_ { 0 }; + Poco::Int64 deleted_at_ { 0 }; + Poco::Int64 updated_at_ { 0 }; + guid guid_ { "" }; // If model push to backend results in an error, // the error is attached to the model for later inspection. - std::string validation_error_; + std::string validation_error_ { "" }; + + bool dirty_ { false }; + bool is_marked_as_deleted_on_server_ { false }; // Flag is set only when sync fails. // Its for viewing purposes only. It should not // be used to check if a model needs to be // pushed to backend. It only means that some // attempt to push failed somewhere. - bool unsynced_; + bool unsynced_ { false }; + protected: + // has to be at the end to "know" about the location of all members inline static const Query query { Query::Table(), Query::Columns({ diff --git a/src/model/client.h b/src/model/client.h index f00409333e..bbd614ed02 100644 --- a/src/model/client.h +++ b/src/model/client.h @@ -18,8 +18,7 @@ namespace toggl { class TOGGL_INTERNAL_EXPORT Client : public BaseModel { Client(ProtectedBase *container) : BaseModel(container) - , wid_(0) - , name_("") {} + {} public: friend class ProtectedBase; @@ -43,8 +42,8 @@ class TOGGL_INTERNAL_EXPORT Client : public BaseModel { bool ResourceCannotBeCreated(const toggl::error &err) const override; private: - Poco::UInt64 wid_; - std::string name_; + Poco::UInt64 wid_ { 0 }; + std::string name_ { "" }; static bool nameHasAlreadyBeenTaken(const error &err); }; diff --git a/src/model/obm_action.h b/src/model/obm_action.h index 8e4b4b0103..dbd96353bd 100644 --- a/src/model/obm_action.h +++ b/src/model/obm_action.h @@ -16,9 +16,7 @@ namespace toggl { class TOGGL_INTERNAL_EXPORT ObmAction : public BaseModel { ObmAction(ProtectedBase *container) : BaseModel(container) - , experiment_id_(0) - , key_("") - , value_("") {} + {} public: friend class ProtectedBase; @@ -44,18 +42,15 @@ class TOGGL_INTERNAL_EXPORT ObmAction : public BaseModel { Json::Value SaveToJSON() const override; private: - Poco::UInt64 experiment_id_; - std::string key_; - std::string value_; + Poco::UInt64 experiment_id_ { 0 }; + std::string key_ { "" }; + std::string value_ { "" }; }; class TOGGL_INTERNAL_EXPORT ObmExperiment : public BaseModel { ObmExperiment(ProtectedBase *container) : BaseModel(container) - , included_(false) - , nr_(0) - , has_seen_(false) - , actions_("") {} + {} public: friend class ProtectedBase; @@ -85,10 +80,10 @@ class TOGGL_INTERNAL_EXPORT ObmExperiment : public BaseModel { std::string ModelURL() const override; private: - bool included_; - Poco::UInt64 nr_; - bool has_seen_; - std::string actions_; + bool included_ { false }; + Poco::UInt64 nr_ { 0 }; + bool has_seen_ { false }; + std::string actions_ { "" }; }; } // namespace toggl diff --git a/src/model/project.h b/src/model/project.h index 913a11fdca..33f26e5b76 100644 --- a/src/model/project.h +++ b/src/model/project.h @@ -17,15 +17,7 @@ class TOGGL_INTERNAL_EXPORT Project : public BaseModel { public: Project(ProtectedBase *container) : BaseModel(container) - , wid_(0) - , cid_(0) - , name_("") - , color_("") - , active_(false) - , private_(false) - , billable_(false) - , client_guid_("") - , client_name_("") {} + {} public: friend class ProtectedBase; @@ -95,19 +87,17 @@ class TOGGL_INTERNAL_EXPORT Project : public BaseModel { bool clientIsInAnotherWorkspace(const toggl::error &err) const; bool onlyAdminsCanChangeProjectVisibility(const toggl::error &err) const; - Poco::UInt64 wid_; - Poco::UInt64 cid_; - std::string name_; - std::string color_; - bool active_; - bool private_; - bool billable_; - std::string client_guid_; - std::string client_name_; + std::string name_ { "" }; + std::string color_ { "" }; + std::string client_guid_ { "" }; + std::string client_name_ { "" }; + Poco::UInt64 wid_ { 0 }; + Poco::UInt64 cid_ { 0 }; + bool active_ { false }; + bool private_ { false }; + bool billable_ { false }; }; -template T *end(T (&ra)[N]); - } // namespace toggl #endif // SRC_PROJECT_H_ diff --git a/src/model/settings.h b/src/model/settings.h index 711defdf65..5c16571116 100644 --- a/src/model/settings.h +++ b/src/model/settings.h @@ -17,71 +17,42 @@ namespace toggl { class TOGGL_INTERNAL_EXPORT Settings : public BaseModel { Settings(ProtectedBase *container) : BaseModel(container) - , use_idle_detection(false) - , menubar_timer(false) - , menubar_project(false) - , dock_icon(false) - , on_top(false) - , reminder(false) - , idle_minutes(0) - , focus_on_shortcut(true) - , reminder_minutes(0) - , manual_mode(false) - , autodetect_proxy(true) - , remind_mon(true) - , remind_tue(true) - , remind_wed(true) - , remind_thu(true) - , remind_fri(true) - , remind_sat(true) - , remind_sun(true) - , remind_starts("") - , remind_ends("") - , autotrack(false) - , open_editor_on_shortcut(false) - , has_seen_beta_offering(false) - , pomodoro(false) - , pomodoro_break(false) - , pomodoro_minutes(0) - , pomodoro_break_minutes(0) - , stop_entry_on_shutdown_sleep(false) - , show_touch_bar(true) - , active_tab(0) {} + {} public: friend class ProtectedBase; virtual ~Settings() {} - bool use_idle_detection; - bool menubar_timer; - bool menubar_project; - bool dock_icon; - bool on_top; - bool reminder; - Poco::Int64 idle_minutes; - bool focus_on_shortcut; - Poco::Int64 reminder_minutes; - bool manual_mode; - bool autodetect_proxy; - bool remind_mon; - bool remind_tue; - bool remind_wed; - bool remind_thu; - bool remind_fri; - bool remind_sat; - bool remind_sun; - std::string remind_starts; - std::string remind_ends; - bool autotrack; - bool open_editor_on_shortcut; - bool has_seen_beta_offering; - bool pomodoro; - bool pomodoro_break; - Poco::Int64 pomodoro_minutes; - Poco::Int64 pomodoro_break_minutes; - bool stop_entry_on_shutdown_sleep; - bool show_touch_bar; - Poco::UInt8 active_tab; + bool use_idle_detection { false }; + bool menubar_timer { false }; + bool menubar_project { false }; + bool dock_icon { false }; + bool on_top { false }; + bool reminder { false }; + Poco::Int64 idle_minutes { 0}; + bool focus_on_shortcut { true }; + Poco::Int64 reminder_minutes { 0 }; + bool manual_mode { false }; + bool autodetect_proxy { true }; + bool remind_mon { true }; + bool remind_tue { true }; + bool remind_wed { true }; + bool remind_thu { true }; + bool remind_fri { true }; + bool remind_sat { true }; + bool remind_sun { true }; + std::string remind_starts { "" }; + std::string remind_ends { "" }; + bool autotrack { false }; + bool open_editor_on_shortcut { false }; + bool has_seen_beta_offering { false }; + bool pomodoro { false }; + bool pomodoro_break { false }; + Poco::Int64 pomodoro_minutes { 0 }; + Poco::Int64 pomodoro_break_minutes { 0 }; + bool stop_entry_on_shutdown_sleep { false }; + bool show_touch_bar { true }; + Poco::UInt8 active_tab { 0 }; bool IsSame(locked &other) const; diff --git a/src/model/tag.h b/src/model/tag.h index 697359e708..3d7864ef56 100644 --- a/src/model/tag.h +++ b/src/model/tag.h @@ -14,8 +14,7 @@ namespace toggl { class TOGGL_INTERNAL_EXPORT Tag : public BaseModel { Tag(ProtectedBase *container) : BaseModel(container) - , wid_(0) - , name_("") {} + {} public: friend class ProtectedBase; @@ -36,8 +35,8 @@ class TOGGL_INTERNAL_EXPORT Tag : public BaseModel { void LoadFromJSON(Json::Value data) override; private: - Poco::UInt64 wid_; - std::string name_; + Poco::UInt64 wid_ { 0 }; + std::string name_ { "" }; }; } // namespace toggl diff --git a/src/model/task.h b/src/model/task.h index e98d387742..351fdb33f8 100644 --- a/src/model/task.h +++ b/src/model/task.h @@ -16,10 +16,7 @@ namespace toggl { class TOGGL_INTERNAL_EXPORT Task : public BaseModel { Task(ProtectedBase *container) : BaseModel(container) - , name_("") - , wid_(0) - , pid_(0) - , active_(false) {} + {} public: friend class ProtectedBase; @@ -50,10 +47,10 @@ class TOGGL_INTERNAL_EXPORT Task : public BaseModel { void LoadFromJSON(Json::Value value) override; private: - std::string name_; - Poco::UInt64 wid_; - Poco::UInt64 pid_; - bool active_; + std::string name_ { " "}; + Poco::UInt64 wid_ { 0 }; + Poco::UInt64 pid_ { 0 }; + bool active_ { false }; }; } // namespace toggl diff --git a/src/model/time_entry.h b/src/model/time_entry.h index 2f995458b7..3bf66ff9af 100644 --- a/src/model/time_entry.h +++ b/src/model/time_entry.h @@ -17,19 +17,7 @@ namespace toggl { class TOGGL_INTERNAL_EXPORT TimeEntry : public BaseModel, public TimedEvent { TimeEntry(ProtectedBase *container) : BaseModel(container) - , wid_(0) - , pid_(0) - , tid_(0) - , billable_(false) - , start_(0) - , stop_(0) - , duration_in_seconds_(0) - , description_("") - , duronly_(false) - , created_with_("") - , project_guid_("") - , unsynced_(false) - , last_start_at_(0) {} + {} public: friend class ProtectedBase; @@ -145,19 +133,19 @@ class TOGGL_INTERNAL_EXPORT TimeEntry : public BaseModel, public TimedEvent { const std::string GroupHash() const; private: - Poco::UInt64 wid_; - Poco::UInt64 pid_; - Poco::UInt64 tid_; - bool billable_; - Poco::Int64 start_; - Poco::Int64 stop_; - Poco::Int64 duration_in_seconds_; - std::string description_; - bool duronly_; - std::string created_with_; - std::string project_guid_; - bool unsynced_; - Poco::Int64 last_start_at_; + std::string description_ { "" }; + std::string created_with_ { "" }; + std::string project_guid_ { "" }; + Poco::UInt64 wid_ { 0 }; + Poco::UInt64 pid_ { 0 }; + Poco::UInt64 tid_ { 0 }; + Poco::Int64 start_ { 0 }; + Poco::Int64 stop_ { 0 }; + Poco::Int64 duration_in_seconds_ { 0 }; + Poco::Int64 last_start_at_ { 0 }; + bool billable_ { false }; + bool duronly_ { false }; + bool unsynced_ { false }; bool setDurationStringHHMMSS(const std::string &value); bool setDurationStringHHMM(const std::string &value); diff --git a/src/model/timeline_event.h b/src/model/timeline_event.h index 4ca8708035..b8b2a28984 100644 --- a/src/model/timeline_event.h +++ b/src/model/timeline_event.h @@ -18,14 +18,7 @@ class TOGGL_INTERNAL_EXPORT TimelineEvent : public BaseModel, public TimedEvent // public because instances get created all over the place TimelineEvent(ProtectedBase *container) : BaseModel(container) - , title_("") - , filename_("") - , start_time_(0) - , end_time_(0) - , duration_(0) - , idle_(false) - , chunked_(false) - , uploaded_(false) {} + {} virtual ~TimelineEvent() {} @@ -80,14 +73,14 @@ class TOGGL_INTERNAL_EXPORT TimelineEvent : public BaseModel, public TimedEvent Json::Value SaveToJSON() const override; private: - std::string title_; - std::string filename_; - Poco::Int64 start_time_; - Poco::Int64 end_time_; - Poco::Int64 duration_; - bool idle_; - bool chunked_; - bool uploaded_; + std::string title_ { "" }; + std::string filename_ { "" }; + Poco::Int64 start_time_ { 0 }; + Poco::Int64 end_time_ { 0 }; + Poco::Int64 duration_ { 0 }; + bool idle_ { false }; + bool chunked_ { false }; + bool uploaded_ { false }; void updateDuration(); }; diff --git a/src/model/user.h b/src/model/user.h index 9390646635..5b5cc8b88a 100644 --- a/src/model/user.h +++ b/src/model/user.h @@ -25,20 +25,7 @@ namespace toggl { class TOGGL_INTERNAL_EXPORT User : public BaseModel { User(ProtectedBase *container) : BaseModel(container) - , api_token_("") - , default_wid_(0) - , since_(0) - , fullname_("") - , email_("") - , record_timeline_(false) - , store_start_and_stop_time_(true) - , timeofday_format_("") - , duration_format_("") - , offline_data_("") - , default_pid_(0) - , default_tid_(0) - , has_loaded_more_(false) - , collapse_entries_(false) {} + {} public: ~User(); @@ -300,22 +287,22 @@ class TOGGL_INTERNAL_EXPORT User : public BaseModel { std::vector> CompressedTimeline( const Poco::LocalDateTime *date = nullptr, bool is_for_upload = true); - std::string api_token_; - Poco::UInt64 default_wid_; + std::string api_token_ { "" }; + std::string fullname_ { "" }; + std::string email_ { "" }; + std::string timeofday_format_ { "" }; + std::string duration_format_ { "" }; + std::string offline_data_ { "" }; + Poco::UInt64 default_wid_ { 0 }; // Unix timestamp of the user data; returned from API - Poco::Int64 since_; - std::string fullname_; - std::string email_; - bool record_timeline_; - bool store_start_and_stop_time_; - std::string timeofday_format_; - std::string duration_format_; - std::string offline_data_; - Poco::UInt64 default_pid_; - Poco::UInt64 default_tid_; - - bool has_loaded_more_; - bool collapse_entries_; + Poco::Int64 since_ { 0 }; + Poco::UInt64 default_pid_ { 0 }; + Poco::UInt64 default_tid_ { 0 }; + bool record_timeline_ { false }; + bool store_start_and_stop_time_ { true }; + + bool has_loaded_more_ { false }; + bool collapse_entries_ { false }; }; template diff --git a/src/model/workspace.h b/src/model/workspace.h index 8a79ec4ffc..4be854680b 100644 --- a/src/model/workspace.h +++ b/src/model/workspace.h @@ -14,13 +14,7 @@ namespace toggl { class TOGGL_INTERNAL_EXPORT Workspace : public BaseModel { Workspace(ProtectedBase *container) : BaseModel(container) - , name_("") - , premium_(false) - , only_admins_may_create_projects_(false) - , admin_(false) - , projects_billable_by_default_(false) - , business_(false) - , locked_time_(0) {} + {} public: friend class ProtectedBase; @@ -68,13 +62,13 @@ class TOGGL_INTERNAL_EXPORT Workspace : public BaseModel { void LoadSettingsFromJson(Json::Value value); private: - std::string name_; - bool premium_; - bool only_admins_may_create_projects_; - bool admin_; - bool projects_billable_by_default_; - bool business_; - time_t locked_time_; + std::string name_ { "" }; + time_t locked_time_ { 0 }; + bool premium_ { false }; + bool only_admins_may_create_projects_ { false }; + bool admin_ { false }; + bool projects_billable_by_default_ { false }; + bool business_ { false }; }; } // namespace toggl From ccb14e5bc78411f96a25f06f78166cc5dd86d4af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C5=99=C3=ADza?= Date: Tue, 24 Mar 2020 20:43:25 +0100 Subject: [PATCH 05/17] Load Workspaces using Bindings (lib) --- src/database/database.cc | 96 ++++++++++++++++------------------------ src/database/database.h | 5 ++- src/model/base_model.h | 13 ++++-- src/model/workspace.cc | 2 +- src/model/workspace.h | 25 +++++++++++ src/util/memory.h | 18 ++++++++ 6 files changed, 96 insertions(+), 63 deletions(-) diff --git a/src/database/database.cc b/src/database/database.cc index 5ada990621..ef5cb883da 100644 --- a/src/database/database.cc +++ b/src/database/database.cc @@ -1107,7 +1107,7 @@ error Database::LoadUserByEmail( } error Database::loadUsersRelatedData(locked &user) { - error err = loadWorkspaces(user->ID(), user->GetRelatedData()->Workspaces); + error err = loadModels(user->ID(), user->GetRelatedData()->Workspaces); if (err != noError) { return err; } @@ -1259,62 +1259,6 @@ error Database::LoadUserByID( return noError; } -error Database::loadWorkspaces(const Poco::UInt64 &UID, - ProtectedContainer &list) { - - if (!UID) { - return error("Cannot load user workspaces without an user ID"); - } - - try { - list.clear(); - - Poco::Mutex::ScopedLock lock(session_m_); - - Poco::Data::Statement select(*session_); - select << - "SELECT local_id, id, uid, name, premium, " - "only_admins_may_create_projects, admin, " - "projects_billable_by_default, " - "is_business, locked_time " - "FROM workspaces " - "WHERE uid = :uid " - "ORDER BY name", - useRef(UID); - error err = last_error("loadWorkspaces"); - if (err != noError) { - return err; - } - Poco::Data::RecordSet rs(select); - while (!select.done()) { - select.execute(); - bool more = rs.moveFirst(); - while (more) { - auto model = list.create(); - model->SetLocalID(rs[0].convert()); - model->SetID(rs[1].convert()); - model->SetUID(rs[2].convert()); - model->SetName(rs[3].convert()); - model->SetPremium(rs[4].convert()); - model->SetOnlyAdminsMayCreateProjects(rs[5].convert()); - model->SetAdmin(rs[6].convert()); - model->SetProjectsBillableByDefault(rs[7].convert()); - model->SetBusiness(rs[8].convert()); - model->SetLockedTime(rs[9].convert()); - model->ClearDirty(); - more = rs.moveNext(); - } - } - } catch(const Poco::Exception& exc) { - return exc.displayText(); - } catch(const std::exception& ex) { - return ex.what(); - } catch(const std::string & ex) { - return ex; - } - return last_error("loadWorkspaces"); -} - error Database::loadClients(const Poco::UInt64 &UID, ProtectedContainer &list) { @@ -4001,4 +3945,42 @@ error Database::saveModel( return noError; } +template +error Database::loadModels(const Poco::UInt64 &UID, ProtectedContainer &list) { + if (!UID) { + return error("Cannot load user workspaces without an user ID"); + } + + try { + list.clear(); + + Poco::Mutex::ScopedLock lock(session_m_); + + Poco::Data::Statement select(*session_); + select << list.GetSelect("uid"), + useRef(UID); + error err = last_error("load_" + list.ModelName()); + if (err != noError) { + return err; + } + Poco::Data::RecordSet rs(select); + while (!select.done()) { + select.execute(); + bool more = rs.moveFirst(); + while (more) { + auto model = list.create(rs); + model->ClearDirty(); + more = rs.moveNext(); + } + } + } catch(const Poco::Exception& exc) { + return exc.displayText(); + } catch(const std::exception& ex) { + return ex.what(); + } catch(const std::string & ex) { + return ex; + } + return last_error("loadWorkspaces"); +} + } // namespace toggl diff --git a/src/database/database.h b/src/database/database.h index 7360596db9..d0117cae2e 100644 --- a/src/database/database.h +++ b/src/database/database.h @@ -287,9 +287,10 @@ class TOGGL_INTERNAL_EXPORT Database { error loadUsersRelatedData(locked &user); - error loadWorkspaces( + template + error loadModels( const Poco::UInt64 &UID, - ProtectedContainer &list); + ProtectedContainer &list); error loadClients( const Poco::UInt64 &UID, diff --git a/src/model/base_model.h b/src/model/base_model.h index 0115f5e87a..e80da2d380 100644 --- a/src/model/base_model.h +++ b/src/model/base_model.h @@ -42,8 +42,8 @@ struct BaseModelQuery { struct Binding { enum Type { - REQUIRED = 0, - OPTIONAL + OPTIONAL = 0, + REQUIRED }; std::string column; db_load_t load; @@ -71,6 +71,12 @@ struct BaseModelQuery { return columns_.size(); } + size_t Offset() const { + if (parent_) + return parent_->ColumnCount(); + return 0; + } + /** * @brief column helper method to retrieve column name from aggregate types (like @ref Binding) * @param item @@ -100,7 +106,7 @@ struct BaseModelQuery { column, [ptr, required](void *that, Poco::Data::RecordSet &rs, size_t index) { auto actuallyThat = reinterpret_cast(that); - if (!rs[index].isEmpty() || required) { + if (!rs[index].isEmpty() || required == Binding::Type::REQUIRED) { (actuallyThat->*ptr) = rs[index].convert(); return true; } @@ -287,6 +293,7 @@ class TOGGL_INTERNAL_EXPORT BaseModel { bool unsynced_ { false }; protected: + std::string modelName {}; // has to be at the end to "know" about the location of all members inline static const Query query { Query::Table(), diff --git a/src/model/workspace.cc b/src/model/workspace.cc index dcbbe8c931..8198468802 100644 --- a/src/model/workspace.cc +++ b/src/model/workspace.cc @@ -86,7 +86,7 @@ void Workspace::LoadSettingsFromJson(Json::Value n) { } std::string Workspace::ModelName() const { - return kModelWorkspace; + return modelName; } std::string Workspace::ModelURL() const { diff --git a/src/model/workspace.h b/src/model/workspace.h index 4be854680b..f499e4ed8d 100644 --- a/src/model/workspace.h +++ b/src/model/workspace.h @@ -15,6 +15,14 @@ class TOGGL_INTERNAL_EXPORT Workspace : public BaseModel { Workspace(ProtectedBase *container) : BaseModel(container) {} + Workspace(ProtectedBase *container, Poco::Data::RecordSet &rs) + : BaseModel(container, rs) + { + for (size_t i = 0; i < query.ColumnCount(); i++) { + bool result = query.columns_[i].load(this, rs, query.Offset() + i); + } + ClearDirty(); + } public: friend class ProtectedBase; @@ -69,6 +77,23 @@ class TOGGL_INTERNAL_EXPORT Workspace : public BaseModel { bool admin_ { false }; bool projects_billable_by_default_ { false }; bool business_ { false }; + + inline static const std::string modelName { kModelWorkspace }; + inline static const Query query { + Query::Table{"workspaces"}, + Query::Columns{ + Query::Bind("name", &Workspace::name_, Query::Binding::REQUIRED), + Query::Bind("premium", &Workspace::premium_, Query::Binding::REQUIRED), + Query::Bind("only_admins_may_create_projects", &Workspace::only_admins_may_create_projects_, Query::Binding::REQUIRED), + Query::Bind("admin", &Workspace::admin_, Query::Binding::REQUIRED), + Query::Bind("projects_billable_by_default", &Workspace::projects_billable_by_default_, Query::Binding::REQUIRED), + Query::Bind("is_business", &Workspace::business_, Query::Binding::REQUIRED), + Query::Bind("locked_time", &Workspace::locked_time_, Query::Binding::REQUIRED), + }, + Query::Join{}, + Query::OrderBy{"name"}, + &BaseModel::query + }; }; } // namespace toggl diff --git a/src/util/memory.h b/src/util/memory.h index cac8d8983d..a68245f173 100644 --- a/src/util/memory.h +++ b/src/util/memory.h @@ -93,6 +93,16 @@ class ProtectedBase { */ const RelatedData *GetRelatedData() const; + template + std::string GetSelect(const std::string &by) const { + return T::query.ToSelect(by); + } + + template + std::string ModelName() const { + return T::modelName; + } + // TODO figure out if it's possible to do without void* virtual bool shift(void *item) { return false; } @@ -252,6 +262,14 @@ class ProtectedContainer : public ProtectedBase { iterator erase(iterator it); + std::string GetSelect(const std::string &by) const { + return ProtectedBase::GetSelect(by); + } + + std::string ModelName() const { + return ProtectedBase::ModelName(); + } + /** * @brief clear - Clear the @ref container_ * @param deleteItems - Set to true if the pointers contained in the @ref container_ should be deleted, too From 76cdeeb7d3b6351490ca3df62185783c5fd0b9b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C5=99=C3=ADza?= Date: Tue, 24 Mar 2020 23:09:01 +0100 Subject: [PATCH 06/17] Fix osx build (lib) --- .../project.pbxproj | 326 ++++++++++-------- 1 file changed, 180 insertions(+), 146 deletions(-) diff --git a/src/lib/osx/TogglDesktopLibrary.xcodeproj/project.pbxproj b/src/lib/osx/TogglDesktopLibrary.xcodeproj/project.pbxproj index 2f53ebb4b5..4c98ffb97f 100644 --- a/src/lib/osx/TogglDesktopLibrary.xcodeproj/project.pbxproj +++ b/src/lib/osx/TogglDesktopLibrary.xcodeproj/project.pbxproj @@ -11,14 +11,9 @@ 7408EDB318C51CEB00CBE8F1 /* const.h in Headers */ = {isa = PBXBuildFile; fileRef = 7408EDAB18C51CEB00CBE8F1 /* const.h */; }; 7408EDB418C51CEB00CBE8F1 /* proxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 7408EDAC18C51CEB00CBE8F1 /* proxy.h */; }; 7408EDB518C51CEB00CBE8F1 /* feedback.h in Headers */ = {isa = PBXBuildFile; fileRef = 7408EDAD18C51CEB00CBE8F1 /* feedback.h */; }; - 7408EDB718C51CEB00CBE8F1 /* formatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 7408EDAF18C51CEB00CBE8F1 /* formatter.h */; }; 7408EDB818C51CEB00CBE8F1 /* feedback.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7408EDB018C51CEB00CBE8F1 /* feedback.cc */; }; - 741951C91B41FCE500FA2724 /* migrations.cc in Sources */ = {isa = PBXBuildFile; fileRef = 741951C71B41FCE500FA2724 /* migrations.cc */; }; - 741951CA1B41FCE500FA2724 /* migrations.h in Headers */ = {isa = PBXBuildFile; fileRef = 741951C81B41FCE500FA2724 /* migrations.h */; }; 7426535E1BEAD91900F0944C /* help_article.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7426535C1BEAD91900F0944C /* help_article.cc */; }; 7426535F1BEAD91900F0944C /* help_article.h in Headers */ = {isa = PBXBuildFile; fileRef = 7426535D1BEAD91900F0944C /* help_article.h */; }; - 743024141AEFA819006DC911 /* autotracker.cc in Sources */ = {isa = PBXBuildFile; fileRef = 743024121AEFA819006DC911 /* autotracker.cc */; }; - 743024151AEFA819006DC911 /* autotracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 743024131AEFA819006DC911 /* autotracker.h */; }; 7458ED291A355746007B529E /* idle.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7458ED271A355746007B529E /* idle.cc */; }; 7458ED2A1A355746007B529E /* idle.h in Headers */ = {isa = PBXBuildFile; fileRef = 7458ED281A355746007B529E /* idle.h */; }; 745E84F5194953A70065E49A /* gui.cc in Sources */ = {isa = PBXBuildFile; fileRef = 745E84F3194953A70065E49A /* gui.cc */; }; @@ -31,61 +26,73 @@ 7484A2AC18887BEE0025A88B /* toggl_api_private.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7484A2A618887BEE0025A88B /* toggl_api_private.cc */; }; 748A0F401B388CCA0001A41E /* urls.cc in Sources */ = {isa = PBXBuildFile; fileRef = 748A0F3E1B388CCA0001A41E /* urls.cc */; }; 748A0F411B388CCA0001A41E /* urls.h in Headers */ = {isa = PBXBuildFile; fileRef = 748A0F3F1B388CCA0001A41E /* urls.h */; }; - 748B7DA51AC5963B00FE01D2 /* custom_error_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 748B7D9D1AC5963B00FE01D2 /* custom_error_handler.cc */; }; - 748B7DA61AC5963B00FE01D2 /* custom_error_handler.h in Headers */ = {isa = PBXBuildFile; fileRef = 748B7D9E1AC5963B00FE01D2 /* custom_error_handler.h */; }; 748B7DA71AC5963B00FE01D2 /* model_change.cc in Sources */ = {isa = PBXBuildFile; fileRef = 748B7D9F1AC5963B00FE01D2 /* model_change.cc */; }; 748B7DA81AC5963B00FE01D2 /* model_change.h in Headers */ = {isa = PBXBuildFile; fileRef = 748B7DA01AC5963B00FE01D2 /* model_change.h */; }; 748B7DA91AC5963B00FE01D2 /* netconf.cc in Sources */ = {isa = PBXBuildFile; fileRef = 748B7DA11AC5963B00FE01D2 /* netconf.cc */; }; 748B7DAA1AC5963B00FE01D2 /* netconf.h in Headers */ = {isa = PBXBuildFile; fileRef = 748B7DA21AC5963B00FE01D2 /* netconf.h */; }; - 748B7DAB1AC5963B00FE01D2 /* settings.cc in Sources */ = {isa = PBXBuildFile; fileRef = 748B7DA31AC5963B00FE01D2 /* settings.cc */; }; - 748B7DAC1AC5963B00FE01D2 /* settings.h in Headers */ = {isa = PBXBuildFile; fileRef = 748B7DA41AC5963B00FE01D2 /* settings.h */; }; - 7497E90A1BEA786A00517BAF /* obm_action.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7497E9081BEA786A00517BAF /* obm_action.cc */; }; - 7497E90B1BEA786A00517BAF /* obm_action.h in Headers */ = {isa = PBXBuildFile; fileRef = 7497E9091BEA786A00517BAF /* obm_action.h */; }; 74A026E11A884D5A0087570A /* liblua.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 74A026E01A884D5A0087570A /* liblua.a */; }; 74AA947A18091AE10000539F /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 74AA947918091AE10000539F /* WebKit.framework */; }; - 74B587BB18BBC77E00E9F6CE /* formatter.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74B587A618BBC77E00E9F6CE /* formatter.cc */; }; - 74B587BC18BBC77E00E9F6CE /* tag.h in Headers */ = {isa = PBXBuildFile; fileRef = 74B587A718BBC77E00E9F6CE /* tag.h */; }; - 74B587BE18BBC77E00E9F6CE /* task.h in Headers */ = {isa = PBXBuildFile; fileRef = 74B587A918BBC77E00E9F6CE /* task.h */; }; - 74B587BF18BBC77E00E9F6CE /* user.h in Headers */ = {isa = PBXBuildFile; fileRef = 74B587AA18BBC77E00E9F6CE /* user.h */; }; - 74B587C018BBC77E00E9F6CE /* client.h in Headers */ = {isa = PBXBuildFile; fileRef = 74B587AB18BBC77E00E9F6CE /* client.h */; }; - 74B587C118BBC77E00E9F6CE /* project.h in Headers */ = {isa = PBXBuildFile; fileRef = 74B587AC18BBC77E00E9F6CE /* project.h */; }; - 74B587C218BBC77E00E9F6CE /* workspace.h in Headers */ = {isa = PBXBuildFile; fileRef = 74B587AD18BBC77E00E9F6CE /* workspace.h */; }; - 74B587C318BBC77E00E9F6CE /* time_entry.h in Headers */ = {isa = PBXBuildFile; fileRef = 74B587AE18BBC77E00E9F6CE /* time_entry.h */; }; 74B587C418BBC77E00E9F6CE /* related_data.h in Headers */ = {isa = PBXBuildFile; fileRef = 74B587AF18BBC77E00E9F6CE /* related_data.h */; }; 74B587C518BBC77E00E9F6CE /* batch_update_result.h in Headers */ = {isa = PBXBuildFile; fileRef = 74B587B018BBC77E00E9F6CE /* batch_update_result.h */; }; - 74B587C618BBC77E00E9F6CE /* tag.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74B587B118BBC77E00E9F6CE /* tag.cc */; }; - 74B587C818BBC77E00E9F6CE /* task.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74B587B318BBC77E00E9F6CE /* task.cc */; }; - 74B587C918BBC77E00E9F6CE /* user.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74B587B418BBC77E00E9F6CE /* user.cc */; }; - 74B587CA18BBC77E00E9F6CE /* client.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74B587B518BBC77E00E9F6CE /* client.cc */; }; - 74B587CB18BBC77E00E9F6CE /* project.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74B587B618BBC77E00E9F6CE /* project.cc */; }; - 74B587CC18BBC77E00E9F6CE /* workspace.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74B587B718BBC77E00E9F6CE /* workspace.cc */; }; - 74B587CD18BBC77E00E9F6CE /* time_entry.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74B587B818BBC77E00E9F6CE /* time_entry.cc */; }; 74B587CE18BBC77E00E9F6CE /* related_data.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74B587B918BBC77E00E9F6CE /* related_data.cc */; }; 74B587CF18BBC77E00E9F6CE /* batch_update_result.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74B587BA18BBC77E00E9F6CE /* batch_update_result.cc */; }; - 74BAD32918BEC4FD002FD4CF /* base_model.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74BAD32718BEC4FD002FD4CF /* base_model.cc */; }; - 74BAD32A18BEC4FD002FD4CF /* base_model.h in Headers */ = {isa = PBXBuildFile; fileRef = 74BAD32818BEC4FD002FD4CF /* base_model.h */; }; 74BC59DA1A37C6790081104D /* error.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74BC59D81A37C6790081104D /* error.cc */; }; 74BC59DB1A37C6790081104D /* error.h in Headers */ = {isa = PBXBuildFile; fileRef = 74BC59D91A37C6790081104D /* error.h */; }; 74CAAD0318185A9B001B77BB /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 74CAAD0218185A9B001B77BB /* Carbon.framework */; }; 74CAAD19181860F7001B77BB /* get_focused_window_mac.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74CAAD10181860F7001B77BB /* get_focused_window_mac.cc */; }; 74CAAD1A181860F7001B77BB /* get_focused_window.h in Headers */ = {isa = PBXBuildFile; fileRef = 74CAAD11181860F7001B77BB /* get_focused_window.h */; }; - 74CAAD1E181860F7001B77BB /* timeline_event.h in Headers */ = {isa = PBXBuildFile; fileRef = 74CAAD15181860F7001B77BB /* timeline_event.h */; }; 74CAAD1F181860F7001B77BB /* timeline_notifications.h in Headers */ = {isa = PBXBuildFile; fileRef = 74CAAD16181860F7001B77BB /* timeline_notifications.h */; }; 74CAAD20181860F7001B77BB /* timeline_uploader.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74CAAD17181860F7001B77BB /* timeline_uploader.cc */; }; 74CAAD21181860F7001B77BB /* timeline_uploader.h in Headers */ = {isa = PBXBuildFile; fileRef = 74CAAD18181860F7001B77BB /* timeline_uploader.h */; }; 74CBDA3A19F97740008494FE /* jsoncpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 74CBDA3919F97740008494FE /* jsoncpp.cpp */; }; - 74DF24E51B414BD8000179AE /* timeline_event.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74DF24E41B414BD8000179AE /* timeline_event.cc */; }; 74E16831180F26D90026261C /* websocket_client.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74E1682F180F26D90026261C /* websocket_client.cc */; }; 74E16832180F26D90026261C /* websocket_client.h in Headers */ = {isa = PBXBuildFile; fileRef = 74E16830180F26D90026261C /* websocket_client.h */; }; 74EB0F1717F9A2600046ABC1 /* https_client.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74EB0F1517F9A2600046ABC1 /* https_client.cc */; }; 74EB0F1817F9A2600046ABC1 /* https_client.h in Headers */ = {isa = PBXBuildFile; fileRef = 74EB0F1617F9A2600046ABC1 /* https_client.h */; }; 74F7CDDB18199FA300630BD0 /* window_change_recorder.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74F7CDD918199FA300630BD0 /* window_change_recorder.cc */; }; 74F7CDDC18199FA300630BD0 /* window_change_recorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 74F7CDDA18199FA300630BD0 /* window_change_recorder.h */; }; - B8470E4C2334C377000D88CE /* random.h in Headers */ = {isa = PBXBuildFile; fileRef = B8470E4A2334C377000D88CE /* random.h */; }; - B8470E4D2334C377000D88CE /* random.cc in Sources */ = {isa = PBXBuildFile; fileRef = B8470E4B2334C377000D88CE /* random.cc */; }; + B81AC2C4242AB252005FA63D /* random.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC2B9242AB251005FA63D /* random.cc */; }; + B81AC2C6242AB252005FA63D /* custom_error_handler.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC2BB242AB251005FA63D /* custom_error_handler.h */; }; + B81AC2C7242AB252005FA63D /* custom_error_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC2BC242AB251005FA63D /* custom_error_handler.cc */; }; + B81AC2C8242AB252005FA63D /* formatter.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC2BD242AB251005FA63D /* formatter.h */; }; + B81AC2C9242AB252005FA63D /* rectangle.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC2BE242AB251005FA63D /* rectangle.h */; }; + B81AC2CA242AB252005FA63D /* formatter.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC2BF242AB251005FA63D /* formatter.cc */; }; + B81AC2CB242AB252005FA63D /* random.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC2C0242AB251005FA63D /* random.h */; }; + B81AC2CD242AB252005FA63D /* memory_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC2C2242AB252005FA63D /* memory_impl.h */; }; + B81AC2CE242AB252005FA63D /* rectangle.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC2C3242AB252005FA63D /* rectangle.cc */; }; + B81AC2E7242AB282005FA63D /* workspace.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC2CF242AB27C005FA63D /* workspace.h */; }; + B81AC2E8242AB282005FA63D /* workspace.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC2D0242AB27C005FA63D /* workspace.cc */; }; + B81AC2E9242AB282005FA63D /* client.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC2D1242AB27C005FA63D /* client.h */; }; + B81AC2EA242AB282005FA63D /* tag.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC2D2242AB27C005FA63D /* tag.h */; }; + B81AC2EB242AB282005FA63D /* base_model.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC2D3242AB27D005FA63D /* base_model.cc */; }; + B81AC2EC242AB282005FA63D /* project.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC2D4242AB27D005FA63D /* project.h */; }; + B81AC2ED242AB282005FA63D /* time_entry.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC2D5242AB27D005FA63D /* time_entry.cc */; }; + B81AC2EE242AB282005FA63D /* user.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC2D6242AB27D005FA63D /* user.h */; }; + B81AC2EF242AB282005FA63D /* client.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC2D7242AB27D005FA63D /* client.cc */; }; + B81AC2F0242AB282005FA63D /* autotracker.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC2D8242AB27D005FA63D /* autotracker.cc */; }; + B81AC2F1242AB282005FA63D /* obm_action.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC2D9242AB27D005FA63D /* obm_action.h */; }; + B81AC2F2242AB282005FA63D /* autotracker.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC2DA242AB27D005FA63D /* autotracker.h */; }; + B81AC2F3242AB282005FA63D /* task.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC2DB242AB27D005FA63D /* task.cc */; }; + B81AC2F4242AB282005FA63D /* tag.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC2DC242AB27D005FA63D /* tag.cc */; }; + B81AC2F5242AB282005FA63D /* settings.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC2DD242AB27D005FA63D /* settings.cc */; }; + B81AC2F6242AB282005FA63D /* task.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC2DE242AB27D005FA63D /* task.h */; }; + B81AC2F7242AB282005FA63D /* timeline_event.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC2DF242AB27E005FA63D /* timeline_event.h */; }; + B81AC2F8242AB282005FA63D /* settings.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC2E0242AB27E005FA63D /* settings.h */; }; + B81AC2F9242AB282005FA63D /* user.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC2E1242AB27E005FA63D /* user.cc */; }; + B81AC2FA242AB282005FA63D /* base_model.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC2E2242AB27E005FA63D /* base_model.h */; }; + B81AC2FB242AB282005FA63D /* project.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC2E3242AB27E005FA63D /* project.cc */; }; + B81AC2FC242AB282005FA63D /* time_entry.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC2E4242AB27E005FA63D /* time_entry.h */; }; + B81AC2FD242AB282005FA63D /* timeline_event.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC2E5242AB27E005FA63D /* timeline_event.cc */; }; + B81AC2FE242AB282005FA63D /* obm_action.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC2E6242AB27E005FA63D /* obm_action.cc */; }; + B81AC303242AB290005FA63D /* database.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC2FF242AB28F005FA63D /* database.cc */; }; + B81AC304242AB290005FA63D /* database.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC300242AB290005FA63D /* database.h */; }; + B81AC305242AB290005FA63D /* migrations.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC301242AB290005FA63D /* migrations.h */; }; + B81AC306242AB290005FA63D /* migrations.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC302242AB290005FA63D /* migrations.cc */; }; + B81AC309242AB3A3005FA63D /* logger.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81AC307242AB3A3005FA63D /* logger.cc */; }; + B81AC30A242AB3A3005FA63D /* logger.h in Headers */ = {isa = PBXBuildFile; fileRef = B81AC308242AB3A3005FA63D /* logger.h */; }; + B81EB948240EAB1500786DF0 /* memory.cc in Sources */ = {isa = PBXBuildFile; fileRef = B81EB946240EAB1500786DF0 /* memory.cc */; }; + B81EB949240EAB1500786DF0 /* memory.h in Headers */ = {isa = PBXBuildFile; fileRef = B81EB947240EAB1500786DF0 /* memory.h */; }; BA1AB53E235DEAD4000433AE /* MacOSVersionChecker.mm in Sources */ = {isa = PBXBuildFile; fileRef = BA1AB53D235DEAD4000433AE /* MacOSVersionChecker.mm */; }; - BA2DA11C21A6864D0027B7A5 /* rectangle.h in Headers */ = {isa = PBXBuildFile; fileRef = BA2DA11A21A6864D0027B7A5 /* rectangle.h */; }; - BA2DA11D21A6864D0027B7A5 /* rectangle.cc in Sources */ = {isa = PBXBuildFile; fileRef = BA2DA11B21A6864D0027B7A5 /* rectangle.cc */; }; BAD233E321D60A4D0039C742 /* libPocoNet.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BAD233DA21D60A4D0039C742 /* libPocoNet.dylib */; }; BAD233E421D60A4D0039C742 /* libPocoFoundation.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BAD233DB21D60A4D0039C742 /* libPocoFoundation.dylib */; }; BAD233E521D60A4D0039C742 /* libPocoUtil.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BAD233DC21D60A4D0039C742 /* libPocoUtil.dylib */; }; @@ -97,8 +104,6 @@ BAD233EB21D60A4D0039C742 /* libPocoXML.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BAD233E221D60A4D0039C742 /* libPocoXML.dylib */; }; C5DA1F9117F18CB6001C4565 /* libssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C5DA1F9017F18CB6001C4565 /* libssl.a */; }; C5DA1F9317F18CBB001C4565 /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C5DA1F9217F18CBB001C4565 /* libcrypto.a */; }; - C5DA1FAB17F18D7B001C4565 /* database.cc in Sources */ = {isa = PBXBuildFile; fileRef = C5DA1FA417F18D7B001C4565 /* database.cc */; }; - C5DA1FAC17F18D7B001C4565 /* database.h in Headers */ = {isa = PBXBuildFile; fileRef = C5DA1FA517F18D7B001C4565 /* database.h */; }; C5DA1FB117F18D7B001C4565 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = C5DA1FAA17F18D7B001C4565 /* types.h */; }; C5DA1FB617F1942A001C4565 /* toggl_api.cc in Sources */ = {isa = PBXBuildFile; fileRef = C5DA1FB417F1942A001C4565 /* toggl_api.cc */; }; C5DA1FB717F1942A001C4565 /* toggl_api.h in Headers */ = {isa = PBXBuildFile; fileRef = C5DA1FB517F1942A001C4565 /* toggl_api.h */; }; @@ -109,14 +114,9 @@ 7408EDAB18C51CEB00CBE8F1 /* const.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = const.h; path = ../../../const.h; sourceTree = ""; }; 7408EDAC18C51CEB00CBE8F1 /* proxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = proxy.h; path = ../../../proxy.h; sourceTree = ""; }; 7408EDAD18C51CEB00CBE8F1 /* feedback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = feedback.h; path = ../../../feedback.h; sourceTree = ""; }; - 7408EDAF18C51CEB00CBE8F1 /* formatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = formatter.h; path = ../../../formatter.h; sourceTree = ""; }; 7408EDB018C51CEB00CBE8F1 /* feedback.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = feedback.cc; path = ../../../feedback.cc; sourceTree = ""; }; - 741951C71B41FCE500FA2724 /* migrations.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = migrations.cc; path = ../../../migrations.cc; sourceTree = ""; }; - 741951C81B41FCE500FA2724 /* migrations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = migrations.h; path = ../../../migrations.h; sourceTree = ""; }; 7426535C1BEAD91900F0944C /* help_article.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = help_article.cc; path = ../../../help_article.cc; sourceTree = ""; }; 7426535D1BEAD91900F0944C /* help_article.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = help_article.h; path = ../../../help_article.h; sourceTree = ""; }; - 743024121AEFA819006DC911 /* autotracker.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = autotracker.cc; path = ../../../autotracker.cc; sourceTree = ""; }; - 743024131AEFA819006DC911 /* autotracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = autotracker.h; path = ../../../autotracker.h; sourceTree = ""; }; 7458ED271A355746007B529E /* idle.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = idle.cc; path = ../../../idle.cc; sourceTree = ""; }; 7458ED281A355746007B529E /* idle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = idle.h; path = ../../../idle.h; sourceTree = ""; }; 745E84F3194953A70065E49A /* gui.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = gui.cc; path = ../../../gui.cc; sourceTree = ""; }; @@ -129,61 +129,73 @@ 7484A2A618887BEE0025A88B /* toggl_api_private.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = toggl_api_private.cc; path = ../../../toggl_api_private.cc; sourceTree = ""; }; 748A0F3E1B388CCA0001A41E /* urls.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = urls.cc; path = ../../../urls.cc; sourceTree = ""; }; 748A0F3F1B388CCA0001A41E /* urls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = urls.h; path = ../../../urls.h; sourceTree = ""; }; - 748B7D9D1AC5963B00FE01D2 /* custom_error_handler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = custom_error_handler.cc; path = ../../../custom_error_handler.cc; sourceTree = ""; }; - 748B7D9E1AC5963B00FE01D2 /* custom_error_handler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = custom_error_handler.h; path = ../../../custom_error_handler.h; sourceTree = ""; }; 748B7D9F1AC5963B00FE01D2 /* model_change.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = model_change.cc; path = ../../../model_change.cc; sourceTree = ""; }; 748B7DA01AC5963B00FE01D2 /* model_change.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = model_change.h; path = ../../../model_change.h; sourceTree = ""; }; 748B7DA11AC5963B00FE01D2 /* netconf.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = netconf.cc; path = ../../../netconf.cc; sourceTree = ""; }; 748B7DA21AC5963B00FE01D2 /* netconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = netconf.h; path = ../../../netconf.h; sourceTree = ""; }; - 748B7DA31AC5963B00FE01D2 /* settings.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = settings.cc; path = ../../../settings.cc; sourceTree = ""; }; - 748B7DA41AC5963B00FE01D2 /* settings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = settings.h; path = ../../../settings.h; sourceTree = ""; }; - 7497E9081BEA786A00517BAF /* obm_action.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = obm_action.cc; path = ../../../obm_action.cc; sourceTree = ""; }; - 7497E9091BEA786A00517BAF /* obm_action.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = obm_action.h; path = ../../../obm_action.h; sourceTree = ""; }; 74A026E01A884D5A0087570A /* liblua.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblua.a; path = ../../../third_party/lua/install/lib/liblua.a; sourceTree = ""; }; 74AA947918091AE10000539F /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; - 74B587A618BBC77E00E9F6CE /* formatter.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = formatter.cc; path = ../../../formatter.cc; sourceTree = ""; }; - 74B587A718BBC77E00E9F6CE /* tag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tag.h; path = ../../../tag.h; sourceTree = ""; }; - 74B587A918BBC77E00E9F6CE /* task.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = task.h; path = ../../../task.h; sourceTree = ""; }; - 74B587AA18BBC77E00E9F6CE /* user.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = user.h; path = ../../../user.h; sourceTree = ""; }; - 74B587AB18BBC77E00E9F6CE /* client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = client.h; path = ../../../client.h; sourceTree = ""; }; - 74B587AC18BBC77E00E9F6CE /* project.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = project.h; path = ../../../project.h; sourceTree = ""; }; - 74B587AD18BBC77E00E9F6CE /* workspace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = workspace.h; path = ../../../workspace.h; sourceTree = ""; }; - 74B587AE18BBC77E00E9F6CE /* time_entry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = time_entry.h; path = ../../../time_entry.h; sourceTree = ""; }; 74B587AF18BBC77E00E9F6CE /* related_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = related_data.h; path = ../../../related_data.h; sourceTree = ""; }; 74B587B018BBC77E00E9F6CE /* batch_update_result.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = batch_update_result.h; path = ../../../batch_update_result.h; sourceTree = ""; }; - 74B587B118BBC77E00E9F6CE /* tag.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tag.cc; path = ../../../tag.cc; sourceTree = ""; }; - 74B587B318BBC77E00E9F6CE /* task.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = task.cc; path = ../../../task.cc; sourceTree = ""; }; - 74B587B418BBC77E00E9F6CE /* user.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = user.cc; path = ../../../user.cc; sourceTree = ""; }; - 74B587B518BBC77E00E9F6CE /* client.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = client.cc; path = ../../../client.cc; sourceTree = ""; }; - 74B587B618BBC77E00E9F6CE /* project.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = project.cc; path = ../../../project.cc; sourceTree = ""; }; - 74B587B718BBC77E00E9F6CE /* workspace.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = workspace.cc; path = ../../../workspace.cc; sourceTree = ""; }; - 74B587B818BBC77E00E9F6CE /* time_entry.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = time_entry.cc; path = ../../../time_entry.cc; sourceTree = ""; }; 74B587B918BBC77E00E9F6CE /* related_data.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = related_data.cc; path = ../../../related_data.cc; sourceTree = ""; }; 74B587BA18BBC77E00E9F6CE /* batch_update_result.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = batch_update_result.cc; path = ../../../batch_update_result.cc; sourceTree = ""; }; - 74BAD32718BEC4FD002FD4CF /* base_model.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = base_model.cc; path = ../../../base_model.cc; sourceTree = ""; }; - 74BAD32818BEC4FD002FD4CF /* base_model.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = base_model.h; path = ../../../base_model.h; sourceTree = ""; }; 74BC59D81A37C6790081104D /* error.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = error.cc; path = ../../../error.cc; sourceTree = ""; }; 74BC59D91A37C6790081104D /* error.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = error.h; path = ../../../error.h; sourceTree = ""; }; 74CAAD0218185A9B001B77BB /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; }; 74CAAD10181860F7001B77BB /* get_focused_window_mac.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = get_focused_window_mac.cc; path = ../../../get_focused_window_mac.cc; sourceTree = ""; }; 74CAAD11181860F7001B77BB /* get_focused_window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = get_focused_window.h; path = ../../../get_focused_window.h; sourceTree = ""; }; - 74CAAD15181860F7001B77BB /* timeline_event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = timeline_event.h; path = ../../../timeline_event.h; sourceTree = ""; }; 74CAAD16181860F7001B77BB /* timeline_notifications.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = timeline_notifications.h; path = ../../../timeline_notifications.h; sourceTree = ""; }; 74CAAD17181860F7001B77BB /* timeline_uploader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = timeline_uploader.cc; path = ../../../timeline_uploader.cc; sourceTree = ""; }; 74CAAD18181860F7001B77BB /* timeline_uploader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = timeline_uploader.h; path = ../../../timeline_uploader.h; sourceTree = ""; }; 74CBDA3919F97740008494FE /* jsoncpp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jsoncpp.cpp; path = ../../../../third_party/jsoncpp/dist/jsoncpp.cpp; sourceTree = ""; }; - 74DF24E41B414BD8000179AE /* timeline_event.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = timeline_event.cc; path = ../../../timeline_event.cc; sourceTree = ""; }; 74E1682F180F26D90026261C /* websocket_client.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = websocket_client.cc; path = ../../../websocket_client.cc; sourceTree = ""; }; 74E16830180F26D90026261C /* websocket_client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = websocket_client.h; path = ../../../websocket_client.h; sourceTree = ""; }; 74EB0F1517F9A2600046ABC1 /* https_client.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = https_client.cc; path = ../../../https_client.cc; sourceTree = ""; }; 74EB0F1617F9A2600046ABC1 /* https_client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = https_client.h; path = ../../../https_client.h; sourceTree = ""; }; 74F7CDD918199FA300630BD0 /* window_change_recorder.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = window_change_recorder.cc; path = ../../../window_change_recorder.cc; sourceTree = ""; }; 74F7CDDA18199FA300630BD0 /* window_change_recorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = window_change_recorder.h; path = ../../../window_change_recorder.h; sourceTree = ""; }; - B8470E4A2334C377000D88CE /* random.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = random.h; path = ../../../random.h; sourceTree = ""; }; - B8470E4B2334C377000D88CE /* random.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = random.cc; path = ../../../random.cc; sourceTree = ""; }; + B81AC2B9242AB251005FA63D /* random.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = random.cc; path = ../../../util/random.cc; sourceTree = ""; }; + B81AC2BB242AB251005FA63D /* custom_error_handler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = custom_error_handler.h; path = ../../../util/custom_error_handler.h; sourceTree = ""; }; + B81AC2BC242AB251005FA63D /* custom_error_handler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = custom_error_handler.cc; path = ../../../util/custom_error_handler.cc; sourceTree = ""; }; + B81AC2BD242AB251005FA63D /* formatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = formatter.h; path = ../../../util/formatter.h; sourceTree = ""; }; + B81AC2BE242AB251005FA63D /* rectangle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rectangle.h; path = ../../../util/rectangle.h; sourceTree = ""; }; + B81AC2BF242AB251005FA63D /* formatter.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = formatter.cc; path = ../../../util/formatter.cc; sourceTree = ""; }; + B81AC2C0242AB251005FA63D /* random.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = random.h; path = ../../../util/random.h; sourceTree = ""; }; + B81AC2C2242AB252005FA63D /* memory_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = memory_impl.h; path = ../../../util/memory_impl.h; sourceTree = ""; }; + B81AC2C3242AB252005FA63D /* rectangle.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rectangle.cc; path = ../../../util/rectangle.cc; sourceTree = ""; }; + B81AC2CF242AB27C005FA63D /* workspace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = workspace.h; path = ../../../model/workspace.h; sourceTree = ""; }; + B81AC2D0242AB27C005FA63D /* workspace.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = workspace.cc; path = ../../../model/workspace.cc; sourceTree = ""; }; + B81AC2D1242AB27C005FA63D /* client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = client.h; path = ../../../model/client.h; sourceTree = ""; }; + B81AC2D2242AB27C005FA63D /* tag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tag.h; path = ../../../model/tag.h; sourceTree = ""; }; + B81AC2D3242AB27D005FA63D /* base_model.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = base_model.cc; path = ../../../model/base_model.cc; sourceTree = ""; }; + B81AC2D4242AB27D005FA63D /* project.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = project.h; path = ../../../model/project.h; sourceTree = ""; }; + B81AC2D5242AB27D005FA63D /* time_entry.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = time_entry.cc; path = ../../../model/time_entry.cc; sourceTree = ""; }; + B81AC2D6242AB27D005FA63D /* user.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = user.h; path = ../../../model/user.h; sourceTree = ""; }; + B81AC2D7242AB27D005FA63D /* client.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = client.cc; path = ../../../model/client.cc; sourceTree = ""; }; + B81AC2D8242AB27D005FA63D /* autotracker.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = autotracker.cc; path = ../../../model/autotracker.cc; sourceTree = ""; }; + B81AC2D9242AB27D005FA63D /* obm_action.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = obm_action.h; path = ../../../model/obm_action.h; sourceTree = ""; }; + B81AC2DA242AB27D005FA63D /* autotracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = autotracker.h; path = ../../../model/autotracker.h; sourceTree = ""; }; + B81AC2DB242AB27D005FA63D /* task.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = task.cc; path = ../../../model/task.cc; sourceTree = ""; }; + B81AC2DC242AB27D005FA63D /* tag.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tag.cc; path = ../../../model/tag.cc; sourceTree = ""; }; + B81AC2DD242AB27D005FA63D /* settings.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = settings.cc; path = ../../../model/settings.cc; sourceTree = ""; }; + B81AC2DE242AB27D005FA63D /* task.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = task.h; path = ../../../model/task.h; sourceTree = ""; }; + B81AC2DF242AB27E005FA63D /* timeline_event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = timeline_event.h; path = ../../../model/timeline_event.h; sourceTree = ""; }; + B81AC2E0242AB27E005FA63D /* settings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = settings.h; path = ../../../model/settings.h; sourceTree = ""; }; + B81AC2E1242AB27E005FA63D /* user.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = user.cc; path = ../../../model/user.cc; sourceTree = ""; }; + B81AC2E2242AB27E005FA63D /* base_model.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = base_model.h; path = ../../../model/base_model.h; sourceTree = ""; }; + B81AC2E3242AB27E005FA63D /* project.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = project.cc; path = ../../../model/project.cc; sourceTree = ""; }; + B81AC2E4242AB27E005FA63D /* time_entry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = time_entry.h; path = ../../../model/time_entry.h; sourceTree = ""; }; + B81AC2E5242AB27E005FA63D /* timeline_event.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = timeline_event.cc; path = ../../../model/timeline_event.cc; sourceTree = ""; }; + B81AC2E6242AB27E005FA63D /* obm_action.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = obm_action.cc; path = ../../../model/obm_action.cc; sourceTree = ""; }; + B81AC2FF242AB28F005FA63D /* database.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = database.cc; path = ../../../database/database.cc; sourceTree = ""; }; + B81AC300242AB290005FA63D /* database.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = database.h; path = ../../../database/database.h; sourceTree = ""; }; + B81AC301242AB290005FA63D /* migrations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = migrations.h; path = ../../../database/migrations.h; sourceTree = ""; }; + B81AC302242AB290005FA63D /* migrations.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = migrations.cc; path = ../../../database/migrations.cc; sourceTree = ""; }; + B81AC307242AB3A3005FA63D /* logger.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = logger.cc; sourceTree = ""; }; + B81AC308242AB3A3005FA63D /* logger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = logger.h; sourceTree = ""; }; + B81EB946240EAB1500786DF0 /* memory.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = memory.cc; path = ../../../util/memory.cc; sourceTree = ""; }; + B81EB947240EAB1500786DF0 /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = memory.h; path = ../../../util/memory.h; sourceTree = ""; }; BA1AB53D235DEAD4000433AE /* MacOSVersionChecker.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MacOSVersionChecker.mm; sourceTree = ""; }; - BA2DA11A21A6864D0027B7A5 /* rectangle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = rectangle.h; path = ../../../rectangle.h; sourceTree = ""; }; - BA2DA11B21A6864D0027B7A5 /* rectangle.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = rectangle.cc; path = ../../../rectangle.cc; sourceTree = ""; }; BAD233DA21D60A4D0039C742 /* libPocoNet.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libPocoNet.dylib; path = ../../../third_party/poco/lib/Darwin/x86_64/libPocoNet.dylib; sourceTree = ""; }; BAD233DB21D60A4D0039C742 /* libPocoFoundation.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libPocoFoundation.dylib; path = ../../../third_party/poco/lib/Darwin/x86_64/libPocoFoundation.dylib; sourceTree = ""; }; BAD233DC21D60A4D0039C742 /* libPocoUtil.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libPocoUtil.dylib; path = ../../../third_party/poco/lib/Darwin/x86_64/libPocoUtil.dylib; sourceTree = ""; }; @@ -199,8 +211,6 @@ C55DA5A217F06A3B00B42178 /* KopsikTarget.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = KopsikTarget.xcconfig; sourceTree = ""; }; C5DA1F9017F18CB6001C4565 /* libssl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libssl.a; path = ../../../third_party/openssl/libssl.a; sourceTree = ""; }; C5DA1F9217F18CBB001C4565 /* libcrypto.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcrypto.a; path = ../../../third_party/openssl/libcrypto.a; sourceTree = ""; }; - C5DA1FA417F18D7B001C4565 /* database.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = database.cc; path = ../../../database.cc; sourceTree = ""; }; - C5DA1FA517F18D7B001C4565 /* database.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = database.h; path = ../../../database.h; sourceTree = ""; }; C5DA1FAA17F18D7B001C4565 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../../../types.h; sourceTree = ""; }; C5DA1FB417F1942A001C4565 /* toggl_api.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = toggl_api.cc; path = ../../../toggl_api.cc; sourceTree = ""; }; C5DA1FB517F1942A001C4565 /* toggl_api.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = toggl_api.h; path = ../../../toggl_api.h; sourceTree = ""; }; @@ -231,6 +241,15 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + B81AC30D242AB3D6005FA63D /* util */ = { + isa = PBXGroup; + children = ( + B81AC307242AB3A3005FA63D /* logger.cc */, + B81AC308242AB3A3005FA63D /* logger.h */, + ); + path = util; + sourceTree = ""; + }; BAD233D921D60A4D0039C742 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -272,27 +291,54 @@ C55DA59E17F06A3B00B42178 /* lib */ = { isa = PBXGroup; children = ( - B8470E4B2334C377000D88CE /* random.cc */, - B8470E4A2334C377000D88CE /* random.h */, + B81AC30D242AB3D6005FA63D /* util */, + B81AC2FF242AB28F005FA63D /* database.cc */, + B81AC300242AB290005FA63D /* database.h */, + B81AC302242AB290005FA63D /* migrations.cc */, + B81AC301242AB290005FA63D /* migrations.h */, + B81AC2D8242AB27D005FA63D /* autotracker.cc */, + B81AC2DA242AB27D005FA63D /* autotracker.h */, + B81AC2D3242AB27D005FA63D /* base_model.cc */, + B81AC2E2242AB27E005FA63D /* base_model.h */, + B81AC2D7242AB27D005FA63D /* client.cc */, + B81AC2D1242AB27C005FA63D /* client.h */, + B81AC2E6242AB27E005FA63D /* obm_action.cc */, + B81AC2D9242AB27D005FA63D /* obm_action.h */, + B81AC2E3242AB27E005FA63D /* project.cc */, + B81AC2D4242AB27D005FA63D /* project.h */, + B81AC2DD242AB27D005FA63D /* settings.cc */, + B81AC2E0242AB27E005FA63D /* settings.h */, + B81AC2DC242AB27D005FA63D /* tag.cc */, + B81AC2D2242AB27C005FA63D /* tag.h */, + B81AC2DB242AB27D005FA63D /* task.cc */, + B81AC2DE242AB27D005FA63D /* task.h */, + B81AC2D5242AB27D005FA63D /* time_entry.cc */, + B81AC2E4242AB27E005FA63D /* time_entry.h */, + B81AC2E5242AB27E005FA63D /* timeline_event.cc */, + B81AC2DF242AB27E005FA63D /* timeline_event.h */, + B81AC2E1242AB27E005FA63D /* user.cc */, + B81AC2D6242AB27D005FA63D /* user.h */, + B81AC2D0242AB27C005FA63D /* workspace.cc */, + B81AC2CF242AB27C005FA63D /* workspace.h */, + B81AC2BC242AB251005FA63D /* custom_error_handler.cc */, + B81AC2BB242AB251005FA63D /* custom_error_handler.h */, + B81AC2BF242AB251005FA63D /* formatter.cc */, + B81AC2BD242AB251005FA63D /* formatter.h */, + B81AC2C2242AB252005FA63D /* memory_impl.h */, + B81AC2B9242AB251005FA63D /* random.cc */, + B81AC2C0242AB251005FA63D /* random.h */, + B81AC2C3242AB252005FA63D /* rectangle.cc */, + B81AC2BE242AB251005FA63D /* rectangle.h */, + B81EB946240EAB1500786DF0 /* memory.cc */, + B81EB947240EAB1500786DF0 /* memory.h */, 7426535C1BEAD91900F0944C /* help_article.cc */, 7426535D1BEAD91900F0944C /* help_article.h */, - 7497E9081BEA786A00517BAF /* obm_action.cc */, - 7497E9091BEA786A00517BAF /* obm_action.h */, - 741951C71B41FCE500FA2724 /* migrations.cc */, - 741951C81B41FCE500FA2724 /* migrations.h */, - 74DF24E41B414BD8000179AE /* timeline_event.cc */, 748A0F3E1B388CCA0001A41E /* urls.cc */, 748A0F3F1B388CCA0001A41E /* urls.h */, - 743024121AEFA819006DC911 /* autotracker.cc */, - 743024131AEFA819006DC911 /* autotracker.h */, - 748B7D9D1AC5963B00FE01D2 /* custom_error_handler.cc */, - 748B7D9E1AC5963B00FE01D2 /* custom_error_handler.h */, 748B7D9F1AC5963B00FE01D2 /* model_change.cc */, 748B7DA01AC5963B00FE01D2 /* model_change.h */, 748B7DA11AC5963B00FE01D2 /* netconf.cc */, 748B7DA21AC5963B00FE01D2 /* netconf.h */, - 748B7DA31AC5963B00FE01D2 /* settings.cc */, - 748B7DA41AC5963B00FE01D2 /* settings.h */, 74699F691A67053600691986 /* analytics.cc */, 74699F6A1A67053600691986 /* analytics.h */, 74BC59D81A37C6790081104D /* error.cc */, @@ -306,27 +352,9 @@ 7408EDAB18C51CEB00CBE8F1 /* const.h */, 7408EDAC18C51CEB00CBE8F1 /* proxy.h */, 7408EDAD18C51CEB00CBE8F1 /* feedback.h */, - 7408EDAF18C51CEB00CBE8F1 /* formatter.h */, 7408EDB018C51CEB00CBE8F1 /* feedback.cc */, - 74BAD32718BEC4FD002FD4CF /* base_model.cc */, - 74BAD32818BEC4FD002FD4CF /* base_model.h */, - 74B587A618BBC77E00E9F6CE /* formatter.cc */, - 74B587A718BBC77E00E9F6CE /* tag.h */, - 74B587A918BBC77E00E9F6CE /* task.h */, - 74B587AA18BBC77E00E9F6CE /* user.h */, - 74B587AB18BBC77E00E9F6CE /* client.h */, - 74B587AC18BBC77E00E9F6CE /* project.h */, - 74B587AD18BBC77E00E9F6CE /* workspace.h */, - 74B587AE18BBC77E00E9F6CE /* time_entry.h */, 74B587AF18BBC77E00E9F6CE /* related_data.h */, 74B587B018BBC77E00E9F6CE /* batch_update_result.h */, - 74B587B118BBC77E00E9F6CE /* tag.cc */, - 74B587B318BBC77E00E9F6CE /* task.cc */, - 74B587B418BBC77E00E9F6CE /* user.cc */, - 74B587B518BBC77E00E9F6CE /* client.cc */, - 74B587B618BBC77E00E9F6CE /* project.cc */, - 74B587B718BBC77E00E9F6CE /* workspace.cc */, - 74B587B818BBC77E00E9F6CE /* time_entry.cc */, 74B587B918BBC77E00E9F6CE /* related_data.cc */, 74B587BA18BBC77E00E9F6CE /* batch_update_result.cc */, 7484A2A218887BEE0025A88B /* toggl_api_private.h */, @@ -337,7 +365,6 @@ 74F7CDDA18199FA300630BD0 /* window_change_recorder.h */, 74CAAD10181860F7001B77BB /* get_focused_window_mac.cc */, 74CAAD11181860F7001B77BB /* get_focused_window.h */, - 74CAAD15181860F7001B77BB /* timeline_event.h */, 74CAAD16181860F7001B77BB /* timeline_notifications.h */, 74CAAD17181860F7001B77BB /* timeline_uploader.cc */, 74CAAD18181860F7001B77BB /* timeline_uploader.h */, @@ -347,14 +374,10 @@ 74EB0F1617F9A2600046ABC1 /* https_client.h */, C5DA1FB417F1942A001C4565 /* toggl_api.cc */, C5DA1FB517F1942A001C4565 /* toggl_api.h */, - C5DA1FA417F18D7B001C4565 /* database.cc */, - C5DA1FA517F18D7B001C4565 /* database.h */, C5DA1FAA17F18D7B001C4565 /* types.h */, C55DA5A117F06A3B00B42178 /* KopsikProj.xcconfig */, C55DA5A217F06A3B00B42178 /* KopsikTarget.xcconfig */, C55DA59F17F06A3B00B42178 /* Supporting Files */, - BA2DA11A21A6864D0027B7A5 /* rectangle.h */, - BA2DA11B21A6864D0027B7A5 /* rectangle.cc */, BA1AB53D235DEAD4000433AE /* MacOSVersionChecker.mm */, ); name = lib; @@ -376,46 +399,49 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + B81AC2EE242AB282005FA63D /* user.h in Headers */, 745E84F6194953A70065E49A /* gui.h in Headers */, 7408EDB418C51CEB00CBE8F1 /* proxy.h in Headers */, - 74B587BC18BBC77E00E9F6CE /* tag.h in Headers */, - 74B587C018BBC77E00E9F6CE /* client.h in Headers */, + B81AC2EC242AB282005FA63D /* project.h in Headers */, + B81AC305242AB290005FA63D /* migrations.h in Headers */, 74BC59DB1A37C6790081104D /* error.h in Headers */, - 74B587C318BBC77E00E9F6CE /* time_entry.h in Headers */, + B81AC2F7242AB282005FA63D /* timeline_event.h in Headers */, + B81AC2F6242AB282005FA63D /* task.h in Headers */, 74B587C418BBC77E00E9F6CE /* related_data.h in Headers */, - 748B7DAC1AC5963B00FE01D2 /* settings.h in Headers */, - 74B587BE18BBC77E00E9F6CE /* task.h in Headers */, 74699F6C1A67053600691986 /* analytics.h in Headers */, 748B7DAA1AC5963B00FE01D2 /* netconf.h in Headers */, - 743024151AEFA819006DC911 /* autotracker.h in Headers */, + B81AC2F8242AB282005FA63D /* settings.h in Headers */, + B81EB949240EAB1500786DF0 /* memory.h in Headers */, 748B7DA81AC5963B00FE01D2 /* model_change.h in Headers */, - 74B587C218BBC77E00E9F6CE /* workspace.h in Headers */, - BA2DA11C21A6864D0027B7A5 /* rectangle.h in Headers */, 74CAAD1F181860F7001B77BB /* timeline_notifications.h in Headers */, - 74B587BF18BBC77E00E9F6CE /* user.h in Headers */, - 748B7DA61AC5963B00FE01D2 /* custom_error_handler.h in Headers */, - 74B587C118BBC77E00E9F6CE /* project.h in Headers */, - 741951CA1B41FCE500FA2724 /* migrations.h in Headers */, + B81AC2C9242AB252005FA63D /* rectangle.h in Headers */, + B81AC2F1242AB282005FA63D /* obm_action.h in Headers */, 7408EDB318C51CEB00CBE8F1 /* const.h in Headers */, + B81AC2E9242AB282005FA63D /* client.h in Headers */, + B81AC2FA242AB282005FA63D /* base_model.h in Headers */, C5DA1FB717F1942A001C4565 /* toggl_api.h in Headers */, 7484A2AA18887BEE0025A88B /* context.h in Headers */, - 74CAAD1E181860F7001B77BB /* timeline_event.h in Headers */, + B81AC2F2242AB282005FA63D /* autotracker.h in Headers */, + B81AC2EA242AB282005FA63D /* tag.h in Headers */, + B81AC2C6242AB252005FA63D /* custom_error_handler.h in Headers */, 74F7CDDC18199FA300630BD0 /* window_change_recorder.h in Headers */, 7408EDB518C51CEB00CBE8F1 /* feedback.h in Headers */, - 7408EDB718C51CEB00CBE8F1 /* formatter.h in Headers */, + B81AC2CD242AB252005FA63D /* memory_impl.h in Headers */, + B81AC2E7242AB282005FA63D /* workspace.h in Headers */, + B81AC2CB242AB252005FA63D /* random.h in Headers */, 74CAAD1A181860F7001B77BB /* get_focused_window.h in Headers */, 7458ED2A1A355746007B529E /* idle.h in Headers */, C5DA1FB117F18D7B001C4565 /* types.h in Headers */, 74E16832180F26D90026261C /* websocket_client.h in Headers */, + B81AC2C8242AB252005FA63D /* formatter.h in Headers */, 7484A2A818887BEE0025A88B /* toggl_api_private.h in Headers */, + B81AC2FC242AB282005FA63D /* time_entry.h in Headers */, 748A0F411B388CCA0001A41E /* urls.h in Headers */, 74EB0F1817F9A2600046ABC1 /* https_client.h in Headers */, - B8470E4C2334C377000D88CE /* random.h in Headers */, - 7497E90B1BEA786A00517BAF /* obm_action.h in Headers */, - 74BAD32A18BEC4FD002FD4CF /* base_model.h in Headers */, + B81AC304242AB290005FA63D /* database.h in Headers */, 7426535F1BEAD91900F0944C /* help_article.h in Headers */, 74B587C518BBC77E00E9F6CE /* batch_update_result.h in Headers */, - C5DA1FAC17F18D7B001C4565 /* database.h in Headers */, + B81AC30A242AB3A3005FA63D /* logger.h in Headers */, 74CAAD21181860F7001B77BB /* timeline_uploader.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -497,43 +523,45 @@ files = ( 748B7DA91AC5963B00FE01D2 /* netconf.cc in Sources */, 74BC59DA1A37C6790081104D /* error.cc in Sources */, + B81AC2F5242AB282005FA63D /* settings.cc in Sources */, 74CAAD19181860F7001B77BB /* get_focused_window_mac.cc in Sources */, 74F7CDDB18199FA300630BD0 /* window_change_recorder.cc in Sources */, - 7497E90A1BEA786A00517BAF /* obm_action.cc in Sources */, 748A0F401B388CCA0001A41E /* urls.cc in Sources */, 74EB0F1717F9A2600046ABC1 /* https_client.cc in Sources */, - 74B587C918BBC77E00E9F6CE /* user.cc in Sources */, - 74B587BB18BBC77E00E9F6CE /* formatter.cc in Sources */, 74B587CE18BBC77E00E9F6CE /* related_data.cc in Sources */, - 741951C91B41FCE500FA2724 /* migrations.cc in Sources */, - 74B587CC18BBC77E00E9F6CE /* workspace.cc in Sources */, + B81AC2EF242AB282005FA63D /* client.cc in Sources */, 748B7DA71AC5963B00FE01D2 /* model_change.cc in Sources */, - 74B587C818BBC77E00E9F6CE /* task.cc in Sources */, + B81AC2F3242AB282005FA63D /* task.cc in Sources */, + B81AC309242AB3A3005FA63D /* logger.cc in Sources */, + B81AC2F0242AB282005FA63D /* autotracker.cc in Sources */, 74CAAD20181860F7001B77BB /* timeline_uploader.cc in Sources */, + B81AC2C7242AB252005FA63D /* custom_error_handler.cc in Sources */, 745E84F5194953A70065E49A /* gui.cc in Sources */, 7484A2AC18887BEE0025A88B /* toggl_api_private.cc in Sources */, 7426535E1BEAD91900F0944C /* help_article.cc in Sources */, - 74DF24E51B414BD8000179AE /* timeline_event.cc in Sources */, - 74B587CB18BBC77E00E9F6CE /* project.cc in Sources */, - 748B7DAB1AC5963B00FE01D2 /* settings.cc in Sources */, + B81AC2E8242AB282005FA63D /* workspace.cc in Sources */, 74B587CF18BBC77E00E9F6CE /* batch_update_result.cc in Sources */, 7484A2AB18887BEE0025A88B /* context.cc in Sources */, - BA2DA11D21A6864D0027B7A5 /* rectangle.cc in Sources */, 74699F6B1A67053600691986 /* analytics.cc in Sources */, 7458ED291A355746007B529E /* idle.cc in Sources */, - 74B587CD18BBC77E00E9F6CE /* time_entry.cc in Sources */, - 74BAD32918BEC4FD002FD4CF /* base_model.cc in Sources */, - 743024141AEFA819006DC911 /* autotracker.cc in Sources */, + B81AC2F9242AB282005FA63D /* user.cc in Sources */, 7408EDB818C51CEB00CBE8F1 /* feedback.cc in Sources */, + B81AC303242AB290005FA63D /* database.cc in Sources */, + B81EB948240EAB1500786DF0 /* memory.cc in Sources */, + B81AC2F4242AB282005FA63D /* tag.cc in Sources */, 74E16831180F26D90026261C /* websocket_client.cc in Sources */, - 74B587CA18BBC77E00E9F6CE /* client.cc in Sources */, + B81AC2FE242AB282005FA63D /* obm_action.cc in Sources */, BA1AB53E235DEAD4000433AE /* MacOSVersionChecker.mm in Sources */, + B81AC2ED242AB282005FA63D /* time_entry.cc in Sources */, + B81AC306242AB290005FA63D /* migrations.cc in Sources */, + B81AC2C4242AB252005FA63D /* random.cc in Sources */, + B81AC2FD242AB282005FA63D /* timeline_event.cc in Sources */, + B81AC2CA242AB252005FA63D /* formatter.cc in Sources */, 7408EDB118C51CEB00CBE8F1 /* proxy.cc in Sources */, - C5DA1FAB17F18D7B001C4565 /* database.cc in Sources */, - 748B7DA51AC5963B00FE01D2 /* custom_error_handler.cc in Sources */, - 74B587C618BBC77E00E9F6CE /* tag.cc in Sources */, + B81AC2CE242AB252005FA63D /* rectangle.cc in Sources */, + B81AC2EB242AB282005FA63D /* base_model.cc in Sources */, C5DA1FB617F1942A001C4565 /* toggl_api.cc in Sources */, - B8470E4D2334C377000D88CE /* random.cc in Sources */, + B81AC2FB242AB282005FA63D /* project.cc in Sources */, 74CBDA3A19F97740008494FE /* jsoncpp.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -611,7 +639,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; @@ -667,7 +695,7 @@ C55DA5AA17F06A3B00B42178 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; CLANG_CXX_LIBRARY = "compiler-default"; CODE_SIGN_IDENTITY = "Mac Developer"; CODE_SIGN_STYLE = Automatic; @@ -690,6 +718,7 @@ ../../../third_party/poco/NetSSL_OpenSSL/include/, ../../../third_party/poco/Crypto/include/, ../../../third_party/jsoncpp/dist, + "./**", ); INSTALL_PATH = "@executable_path/../../Contents/Frameworks"; LIBRARY_SEARCH_PATHS = ( @@ -702,6 +731,8 @@ PRODUCT_NAME = TogglDesktopLibrary; PROVISIONING_PROFILE_SPECIFIER = ""; STRIP_INSTALLED_PRODUCT = NO; + USER_HEADER_SEARCH_PATHS = "../.. ../../model"; + USE_HEADERMAP = YES; }; name = Debug; }; @@ -732,6 +763,7 @@ ../../../third_party/poco/NetSSL_OpenSSL/include/, ../../../third_party/poco/Crypto/include/, ../../../third_party/jsoncpp/dist, + "./**", ); INSTALL_PATH = "@executable_path/../../Contents/Frameworks"; LIBRARY_SEARCH_PATHS = ( @@ -744,6 +776,8 @@ PRODUCT_NAME = TogglDesktopLibrary; PROVISIONING_PROFILE_SPECIFIER = ""; STRIP_INSTALLED_PRODUCT = NO; + USER_HEADER_SEARCH_PATHS = "../.. ../../model"; + USE_HEADERMAP = YES; }; name = Release; }; From 667a7108c64b489b1570ff34c554b2344e564bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C5=99=C3=ADza?= Date: Wed, 25 Mar 2020 12:48:43 +0100 Subject: [PATCH 07/17] Reorganize the VS project on a way to fix build on Windows (lib) --- src/analytics.h | 1 + .../TogglDesktopDLL/TogglDesktopDLL.vcxproj | 74 ++-- .../TogglDesktopDLL.vcxproj.filters | 393 ++++++++++-------- src/util/memory.h | 5 +- 4 files changed, 261 insertions(+), 212 deletions(-) diff --git a/src/analytics.h b/src/analytics.h index 0c0a66593e..457157bd0c 100644 --- a/src/analytics.h +++ b/src/analytics.h @@ -10,6 +10,7 @@ #include #include "proxy.h" +#include "util/memory.h" #include "util/rectangle.h" #include "model/settings.h" diff --git a/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj b/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj index 2fdb711d5b..516383ebfd 100644 --- a/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj +++ b/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj @@ -192,6 +192,7 @@ true false false + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\..\.. true @@ -362,10 +363,10 @@ true TOGGLDESKTOP_DLL_BUILD;JSON_DLL_BUILD;WIN32;NDEBUG;_WINDOWS;_USRDLL;TOGGLDESKTOPDLL_EXPORTS;%(PreprocessorDefinitions) true - $(ProjectDir)..\..\..\..\third_party\poco\openssl\build\include;$(ProjectDir)..\..\..\..\third_party\jsoncpp\dist;$(ProjectDir)..\..\..\..\third_party\poco\Foundation\include;$(ProjectDir)..\..\..\..\third_party\poco\Util\include;$(ProjectDir)..\..\..\..\third_party\poco\Crypto\include;$(ProjectDir)..\..\..\..\third_party\poco\Net\include;$(ProjectDir)..\..\..\..\third_party\poco\NetSSL_OpenSSL\include;$(ProjectDir)..\..\..\..\third_party\poco\Data\include;$(ProjectDir)..\..\..\..\third_party\poco\Data\SQLite\include;$(ProjectDir)..\..\..\..\third_party\poco\Data\SQLite\src;$(ProjectDir)..\..\..\..\third_party\lua\src;$(ProjectDir)..\..\..\..\third_party\luafar;%(AdditionalIncludeDirectories) + $(ProjectDir)..\..\..\..\third_party\poco\openssl\build\include;$(ProjectDir)..\..\..\..\third_party\jsoncpp\dist;$(ProjectDir)..\..\..\..\third_party\poco\Foundation\include;$(ProjectDir)..\..\..\..\third_party\poco\Util\include;$(ProjectDir)..\..\..\..\third_party\poco\Crypto\include;$(ProjectDir)..\..\..\..\third_party\poco\Net\include;$(ProjectDir)..\..\..\..\third_party\poco\NetSSL_OpenSSL\include;$(ProjectDir)..\..\..\..\third_party\poco\Data\include;$(ProjectDir)..\..\..\..\third_party\poco\Data\SQLite\include;$(ProjectDir)..\..\..\..\third_party\poco\Data\SQLite\src;$(ProjectDir)..\..\..\..\third_party\lua\src;$(ProjectDir)..\..\..\..\third_party\luafar;%(AdditionalIncludeDirectories);$(SolutionDir)..\..\..\ true false - stdcpp17 + stdcpplatest Windows @@ -497,17 +498,11 @@ - - - - - - @@ -515,27 +510,36 @@ + + + + + + + + + + + + - - - - - - - - - + + + + + + + - @@ -577,15 +581,10 @@ - - - - - @@ -593,26 +592,33 @@ + + + + + + + + + + + + - - - - - - - - - - + + + + + + - false false diff --git a/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj.filters b/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj.filters index 9fd08639ab..3eb2827a77 100644 --- a/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj.filters +++ b/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj.filters @@ -13,6 +13,30 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + {47869713-b83b-49b7-9ecc-323830cdfd9a} + + + {14cf0637-fe1c-4e96-b8ef-80e73f0e403b} + + + {cf7d965d-3741-4e72-95da-20c316b1b958} + + + {79237961-63c3-4dcf-b0fb-46c7d441fe99} + + + {ed60ba8b-64ab-4696-a21f-5f250598ccad} + + + {605756cf-c57b-4d96-9827-feff31ff1e35} + + + {ca0e9d72-6afc-449e-ba66-c6acc5f82577} + + + {56f6a37e-9f9c-486a-a353-b76927622170} + @@ -24,36 +48,18 @@ Header Files - - Header Files - - - Header Files - Header Files - - Header Files - Header Files Header Files - - Header Files - - - Header Files - Header Files - - Header Files - Header Files @@ -63,167 +69,194 @@ Header Files - - Header Files - Header Files Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files + + Header Files\model + + + Header Files\model + + + Header Files\model + - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua - Header Files + Header Files\lua + + + Header Files\lua - Header Files + Header Files\lua - - Header Files + + Header Files\model - - Header Files + + Header Files\model - - Header Files + + Header Files\util - - Header Files + + Header Files\util - - Header Files + + Header Files\util - - Header Files + + Header Files\util - - Header Files + + Header Files\util - - Header Files + + Header Files\util - - Header Files + + Header Files\util - - Header Files + + Header Files\model - - Header Files + + Header Files\model + + + Header Files\model + + + Header Files\model + + + Header Files\model + + + Header Files\lua + + + Header Files\database + + + Header Files\database @@ -233,30 +266,15 @@ Source Files - - Source Files - Source Files - - Source Files - Source Files - - Source Files - - - Source Files - Source Files - - Source Files - Source Files @@ -269,188 +287,209 @@ Source Files - - Source Files - Source Files Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files - - - Source Files + Source Files\lua - Source Files + Source Files\lua + + + Source Files\lua - Source Files + Source Files\lua - Source Files - - - Source Files + Source Files\lua - Source Files + Source Files\lua + + + Source Files\lua - Source Files + Source Files\lua - Source Files - - - Source Files + Source Files\lua - Source Files + Source Files\lua + + + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - Source Files + Source Files\lua - - Source Files + + Source Files\model - - Source Files + + Source Files\model - - Source Files + + Source Files\model - - Source Files + + Source Files\util - - Source Files + + Source Files\util - - Source Files + + Source Files\model - - Source Files + + Source Files\model - - Source Files + + Source Files\util - - Source Files + + Source Files\util - - Source Files + + Source Files\model - - Source Files + + Source Files\model + + + Source Files\model + + + Source Files\model + + + Source Files\model + + + Source Files\model + + + Source Files\model + + + Source Files\lua + + + Source Files\database + + + Source Files\database - + \ No newline at end of file diff --git a/src/util/memory.h b/src/util/memory.h index a68245f173..a4575c1637 100644 --- a/src/util/memory.h +++ b/src/util/memory.h @@ -243,13 +243,16 @@ class ProtectedContainer : public ProtectedBase { friend class iterator; friend class const_iterator; + static inline std::function defaultComparison{ + [](const T* l, const T* r) { return l < r; } + }; /** * @brief ProtectedContainer * @param parent - the parent RelatedData instances (to be passed to the children) * @param comparison - a binary predicate with the signature of bool(const T*, const T*), used to insert items at the right position when creating * TODO Using the comparison predicate has O(N) complexity, we'd very likely be much better off storing everything in a std::set */ - ProtectedContainer(RelatedData *parent, comparison_function comparison = [](const T* l, const T* r){ return l < r; }); + ProtectedContainer(RelatedData *parent, comparison_function comparison = defaultComparison); ProtectedContainer(const ProtectedContainer &o) = delete; ~ProtectedContainer(); From edb043dada130438443b2af5a0f7b84e10330afe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C5=99=C3=ADza?= Date: Fri, 27 Mar 2020 17:52:35 +0100 Subject: [PATCH 08/17] Revert to string-based columns because MSVC hates me (lib) I spent 2 days trying to make this work in Windows but due to MSVC bugs, I have to revert to just doing it with strings and defining columns in the constructor as well --- .../TogglDesktopDLL/TogglDesktopDLL.vcxproj | 5 +- .../TogglDesktopDLL.vcxproj.filters | 4 +- src/model/base_model.h | 101 ++++++++---------- src/model/workspace.h | 50 +++++---- 4 files changed, 77 insertions(+), 83 deletions(-) diff --git a/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj b/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj index 516383ebfd..f57b623e18 100644 --- a/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj +++ b/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj @@ -203,6 +203,7 @@ true false false + $(VC_IncludePath);$(WindowsSDK_IncludePath);;$(SolutionDir)\..\..\.. true @@ -583,7 +584,7 @@ - + @@ -591,7 +592,7 @@ - + diff --git a/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj.filters b/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj.filters index 3eb2827a77..7c608be1c0 100644 --- a/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj.filters +++ b/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj.filters @@ -485,10 +485,10 @@ Source Files\lua - + Source Files\database - + Source Files\database diff --git a/src/model/base_model.h b/src/model/base_model.h index e80da2d380..83aaf74950 100644 --- a/src/model/base_model.h +++ b/src/model/base_model.h @@ -38,20 +38,14 @@ class BatchUpdateResult; * and to not have to handle their serialization in all child classes separately. */ struct BaseModelQuery { - typedef std::function db_load_t; - - struct Binding { - enum Type { - OPTIONAL = 0, - REQUIRED - }; - std::string column; - db_load_t load; - }; + struct Column { + std::string name; + bool required; + }; typedef std::vector Join; typedef std::string Table; - typedef std::vector Columns; + typedef std::vector Columns; typedef std::vector OrderBy; Table table_ {}; @@ -77,13 +71,16 @@ struct BaseModelQuery { return 0; } - /** - * @brief column helper method to retrieve column name from aggregate types (like @ref Binding) - * @param item - * @return column name of the item - */ - static const std::string &column(const std::string &item) { return item; } - static const std::string &column(const Binding &item) { return item.column; } + bool IsRequired(size_t idx) const { + if (parent_ && idx >= Offset()) { + return parent_->IsRequired(idx - Offset()); + } + return columns_[idx].required; + } + + template static const std::string &column(const T &item) { return item; } + template <> static const std::string &column(const Column &item) { return item.name; } + /** * @brief writes a list of columns to @ref ss * Handles case when there's multiple tables and prepends "main" table name to columns without a dot @@ -99,40 +96,48 @@ struct BaseModelQuery { ss << column(i); } }; - - template - static Binding Bind(const std::string &column, Value Class::*ptr, Binding::Type required) { - return { - column, - [ptr, required](void *that, Poco::Data::RecordSet &rs, size_t index) { - auto actuallyThat = reinterpret_cast(that); - if (!rs[index].isEmpty() || required == Binding::Type::REQUIRED) { - (actuallyThat->*ptr) = rs[index].convert(); - return true; - } - return false; - } - }; - } }; class TOGGL_INTERNAL_EXPORT BaseModel { protected: using Query = BaseModelQuery; - BaseModel(ProtectedBase *container) - : container_(container) - {} + inline static std::string modelName {}; + inline static const Query query { + Query::Table(), + Query::Columns { + { "local_id", true }, + { "id", false }, + { "uid", true }, + { "guid", false }, + }, + Query::Join(), + Query::OrderBy(), + nullptr + }; + + template + bool load(Poco::Data::RecordSet &rs, bool required, size_t index, T& member) { + if (!rs[index].isEmpty() || required) { + member = rs[index].convert(); + return true; + } + return false; + } BaseModel(ProtectedBase *container, Poco::Data::RecordSet &rs) : container_(container) { - for (size_t i = 0; i < query.ColumnCount(); i++) { - bool result = query.columns_[i].load(this, rs, i); - } + size_t ptr { query.Offset() }; + load(rs, query.IsRequired(ptr), ptr++, local_id_); + load(rs, query.IsRequired(ptr), ptr++, id_); + load(rs, query.IsRequired(ptr), ptr++, uid_); + load(rs, query.IsRequired(ptr), ptr++, guid_); ClearDirty(); } - + BaseModel(ProtectedBase* container) + : container_(container) + {} virtual ~BaseModel() {} public: @@ -291,22 +296,6 @@ class TOGGL_INTERNAL_EXPORT BaseModel { // pushed to backend. It only means that some // attempt to push failed somewhere. bool unsynced_ { false }; - - protected: - std::string modelName {}; - // has to be at the end to "know" about the location of all members - inline static const Query query { - Query::Table(), - Query::Columns({ - Query::Bind("local_id", &BaseModel::local_id_, Query::Binding::REQUIRED), - Query::Bind("id", &BaseModel::id_, Query::Binding::OPTIONAL), - Query::Bind("uid", &BaseModel::uid_, Query::Binding::REQUIRED), - Query::Bind("guid", &BaseModel::guid_, Query::Binding::OPTIONAL) - }), - Query::Join(), - Query::OrderBy(), - nullptr - }; }; } // namespace toggl diff --git a/src/model/workspace.h b/src/model/workspace.h index f499e4ed8d..ef1e3482f6 100644 --- a/src/model/workspace.h +++ b/src/model/workspace.h @@ -12,17 +12,38 @@ namespace toggl { class TOGGL_INTERNAL_EXPORT Workspace : public BaseModel { - Workspace(ProtectedBase *container) - : BaseModel(container) - {} + inline static const std::string modelName{ kModelWorkspace }; + inline static const Query query{ + Query::Table{"workspaces"}, + Query::Columns { + { "name", true }, + { "premium", true }, + { "only_admins_may_create_projects", true }, + { "admin", true }, + { "projects_billable_by_default", true }, + { "is_business", true }, + { "locked_time", true } + }, + Query::Join{}, + Query::OrderBy{"name"}, + &BaseModel::query + }; Workspace(ProtectedBase *container, Poco::Data::RecordSet &rs) : BaseModel(container, rs) { - for (size_t i = 0; i < query.ColumnCount(); i++) { - bool result = query.columns_[i].load(this, rs, query.Offset() + i); - } + size_t ptr{ query.Offset() }; + load(rs, query.IsRequired(ptr), ptr++, name_); + load(rs, query.IsRequired(ptr), ptr++, premium_); + load(rs, query.IsRequired(ptr), ptr++, only_admins_may_create_projects_); + load(rs, query.IsRequired(ptr), ptr++, admin_); + load(rs, query.IsRequired(ptr), ptr++, projects_billable_by_default_); + load(rs, query.IsRequired(ptr), ptr++, business_); + load(rs, query.IsRequired(ptr), ptr++, locked_time_); ClearDirty(); } + Workspace(ProtectedBase* container) + : BaseModel(container) + {} public: friend class ProtectedBase; @@ -77,23 +98,6 @@ class TOGGL_INTERNAL_EXPORT Workspace : public BaseModel { bool admin_ { false }; bool projects_billable_by_default_ { false }; bool business_ { false }; - - inline static const std::string modelName { kModelWorkspace }; - inline static const Query query { - Query::Table{"workspaces"}, - Query::Columns{ - Query::Bind("name", &Workspace::name_, Query::Binding::REQUIRED), - Query::Bind("premium", &Workspace::premium_, Query::Binding::REQUIRED), - Query::Bind("only_admins_may_create_projects", &Workspace::only_admins_may_create_projects_, Query::Binding::REQUIRED), - Query::Bind("admin", &Workspace::admin_, Query::Binding::REQUIRED), - Query::Bind("projects_billable_by_default", &Workspace::projects_billable_by_default_, Query::Binding::REQUIRED), - Query::Bind("is_business", &Workspace::business_, Query::Binding::REQUIRED), - Query::Bind("locked_time", &Workspace::locked_time_, Query::Binding::REQUIRED), - }, - Query::Join{}, - Query::OrderBy{"name"}, - &BaseModel::query - }; }; } // namespace toggl From 722eb62c8c82aa47e988a6c2d577ae429d5b0fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C5=99=C3=ADza?= Date: Mon, 30 Mar 2020 10:04:15 +0200 Subject: [PATCH 09/17] Inline specialization didn't work in GCC, use a conversion operator instead (lib) --- src/model/base_model.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/model/base_model.h b/src/model/base_model.h index 83aaf74950..2cf43be709 100644 --- a/src/model/base_model.h +++ b/src/model/base_model.h @@ -42,6 +42,10 @@ struct BaseModelQuery { struct Column { std::string name; bool required; + // so printColumns still works + explicit operator std::string() const { + return name; + } }; typedef std::vector Join; typedef std::string Table; @@ -78,9 +82,6 @@ struct BaseModelQuery { return columns_[idx].required; } - template static const std::string &column(const T &item) { return item; } - template <> static const std::string &column(const Column &item) { return item.name; } - /** * @brief writes a list of columns to @ref ss * Handles case when there's multiple tables and prepends "main" table name to columns without a dot @@ -91,9 +92,9 @@ struct BaseModelQuery { if (!first) ss << ", "; first = false; - if (!join_.empty() && column(i).find(".") == std::string::npos) + if (!join_.empty() && std::string(i).find(".") == std::string::npos) ss << table_ << "."; - ss << column(i); + ss << std::string(i); } }; }; From 9bf8bc942a258b73214f73484432c0f09e95b033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C5=99=C3=ADza?= Date: Mon, 30 Mar 2020 18:44:11 +0200 Subject: [PATCH 10/17] Implement the new constructor for every model except Project (lib) Notice how the deleted number count is higher than added now --- src/database/database.cc | 555 +------------------------------------ src/database/database.h | 36 --- src/database/migrations.cc | 13 +- src/model/autotracker.h | 24 ++ src/model/base_model.h | 12 +- src/model/client.h | 21 ++ src/model/obm_action.h | 75 +++++ src/model/tag.h | 21 ++ src/model/task.h | 27 ++ src/model/time_entry.h | 81 ++++++ src/model/timeline_event.h | 36 +++ src/model/workspace.h | 21 +- 12 files changed, 326 insertions(+), 596 deletions(-) diff --git a/src/database/database.cc b/src/database/database.cc index ef5cb883da..4928f6e66c 100644 --- a/src/database/database.cc +++ b/src/database/database.cc @@ -1112,7 +1112,7 @@ error Database::loadUsersRelatedData(locked &user) { return err; } - err = loadClients(user->ID(), user->GetRelatedData()->Clients); + err = loadModels(user->ID(), user->GetRelatedData()->Clients); if (err != noError) { return err; } @@ -1122,37 +1122,37 @@ error Database::loadUsersRelatedData(locked &user) { return err; } - err = loadTasks(user->ID(), user->GetRelatedData()->Tasks); + err = loadModels(user->ID(), user->GetRelatedData()->Tasks); if (err != noError) { return err; } - err = loadTags(user->ID(), user->GetRelatedData()->Tags); + err = loadModels(user->ID(), user->GetRelatedData()->Tags); if (err != noError) { return err; } - err = loadTimeEntries(user->ID(), user->GetRelatedData()->TimeEntries); + err = loadModels(user->ID(), user->GetRelatedData()->TimeEntries); if (err != noError) { return err; } - err = loadAutotrackerRules(user->ID(), user->GetRelatedData()->AutotrackerRules); + err = loadModels(user->ID(), user->GetRelatedData()->AutotrackerRules); if (err != noError) { return err; } - err = loadTimelineEvents(user->ID(), user->GetRelatedData()->TimelineEvents); + err = loadModels(user->ID(), user->GetRelatedData()->TimelineEvents); if (err != noError) { return err; } - err = loadObmActions(user->ID(), user->GetRelatedData()->ObmActions); + err = loadModels(user->ID(), user->GetRelatedData()->ObmActions); if (err != noError) { return err; } - err = loadObmExperiments(user->ID(), user->GetRelatedData()->ObmExperiments); + err = loadModels(user->ID(), user->GetRelatedData()->ObmExperiments); if (err != noError) { return err; } @@ -1259,65 +1259,6 @@ error Database::LoadUserByID( return noError; } -error Database::loadClients(const Poco::UInt64 &UID, - ProtectedContainer &list) { - - if (!UID) { - return error("Cannot load user clients without an user ID"); - } - - try { - list.clear(); - - Poco::Mutex::ScopedLock lock(session_m_); - - Poco::Data::Statement select(*session_); - select << - "SELECT local_id, id, uid, name, guid, wid " - "FROM clients " - "WHERE uid = :uid " - "ORDER BY name", - useRef(UID); - - error err = last_error("loadClients"); - if (err != noError) { - return err; - } - Poco::Data::RecordSet rs(select); - while (!select.done()) { - select.execute(); - bool more = rs.moveFirst(); - while (more) { - auto model = list.create(); - model->SetLocalID(rs[0].convert()); - if (rs[1].isEmpty()) { - model->SetID(0); - } else { - model->SetID(rs[1].convert()); - } - model->SetUID(rs[2].convert()); - model->SetName(rs[3].convert()); - if (rs[4].isEmpty()) { - model->SetGUID(""); - } else { - model->SetGUID(rs[4].convert()); - } - model->SetWID(rs[5].convert()); - model->ClearDirty(); - - more = rs.moveNext(); - } - } - } catch(const Poco::Exception& exc) { - return exc.displayText(); - } catch(const std::exception& ex) { - return ex.what(); - } catch(const std::string & ex) { - return ex; - } - return last_error("loadClients"); -} - error Database::loadProjects(const Poco::UInt64 &UID, ProtectedContainer &list) { @@ -1405,486 +1346,6 @@ error Database::loadProjects(const Poco::UInt64 &UID, return last_error("loadProjects"); } -error Database::loadTasks( - const Poco::UInt64 &UID, - ProtectedContainer &list) { - - if (!UID) { - return error("Cannot load user tasks without an user ID"); - } - - try { - list.clear(); - - Poco::Mutex::ScopedLock lock(session_m_); - - Poco::Data::Statement select(*session_); - select << - "SELECT local_id, id, uid, name, wid, pid, active " - "FROM tasks " - "WHERE uid = :uid " - "ORDER BY name", - useRef(UID); - error err = last_error("loadTasks"); - if (err != noError) { - return err; - } - Poco::Data::RecordSet rs(select); - while (!select.done()) { - select.execute(); - bool more = rs.moveFirst(); - while (more) { - auto model = list.create(); - model->SetLocalID(rs[0].convert()); - if (rs[1].isEmpty()) { - model->SetID(0); - } else { - model->SetID(rs[1].convert()); - } - model->SetUID(rs[2].convert()); - model->SetName(rs[3].convert()); - model->SetWID(rs[4].convert()); - if (rs[5].isEmpty()) { - model->SetPID(0); - } else { - model->SetPID(rs[5].convert()); - } - model->SetActive(rs[6].convert()); - model->ClearDirty(); - - more = rs.moveNext(); - } - } - } catch(const Poco::Exception& exc) { - return exc.displayText(); - } catch(const std::exception& ex) { - return ex.what(); - } catch(const std::string & ex) { - return ex; - } - return last_error("loadTasks"); -} - -error Database::loadTags(const Poco::UInt64 &UID, - ProtectedContainer &list) { - - if (!UID) { - return error("Cannot load user tags without an user ID"); - } - - try { - list.clear(); - - Poco::Mutex::ScopedLock lock(session_m_); - - Poco::Data::Statement select(*session_); - select << - "SELECT local_id, id, uid, name, wid, guid " - "FROM tags " - "WHERE uid = :uid " - "ORDER BY name", - useRef(UID); - error err = last_error("loadTags"); - if (err != noError) { - return err; - } - Poco::Data::RecordSet rs(select); - while (!select.done()) { - select.execute(); - bool more = rs.moveFirst(); - while (more) { - auto model = list.create(); - model->SetLocalID(rs[0].convert()); - if (rs[1].isEmpty()) { - model->SetID(0); - } else { - model->SetID(rs[1].convert()); - } - model->SetUID(rs[2].convert()); - model->SetName(rs[3].convert()); - model->SetWID(rs[4].convert()); - if (rs[5].isEmpty()) { - model->SetGUID(""); - } else { - model->SetGUID(rs[5].convert()); - } - model->ClearDirty(); - - more = rs.moveNext(); - } - } - } catch(const Poco::Exception& exc) { - return exc.displayText(); - } catch(const std::exception& ex) { - return ex.what(); - } catch(const std::string & ex) { - return ex; - } - return last_error("loadTags"); -} - -error Database::loadAutotrackerRules(const Poco::UInt64 &UID, - ProtectedContainer &list) { - - if (!UID) { - return error("Cannot load autotracker rules without an user ID"); - } - - try { - list.clear(); - - Poco::Mutex::ScopedLock lock(session_m_); - - Poco::Data::Statement select(*session_); - select << - "SELECT local_id, uid, term, pid, tid " - "FROM autotracker_settings " - "WHERE uid = :uid " - "ORDER BY term DESC", - useRef(UID); - error err = last_error("loadAutotrackerRules"); - if (err != noError) { - return err; - } - Poco::Data::RecordSet rs(select); - while (!select.done()) { - select.execute(); - bool more = rs.moveFirst(); - while (more) { - auto model = list.create(); - model->SetLocalID(rs[0].convert()); - model->SetUID(rs[1].convert()); - model->SetTerm(rs[2].convert()); - model->SetPID(rs[3].convert()); - if (!rs[4].isEmpty()) { - model->SetTID(rs[4].convert()); - } - model->ClearDirty(); - - more = rs.moveNext(); - } - } - } catch(const Poco::Exception& exc) { - return exc.displayText(); - } catch(const std::exception& ex) { - return ex.what(); - } catch(const std::string & ex) { - return ex; - } - return last_error("loadAutotrackerRules"); -} - -error Database::loadObmActions( - const Poco::UInt64 &UID, - ProtectedContainer &list) { - - if (!UID) { - return error("Cannot load OBM actions without an user ID"); - } - - try { - list.clear(); - - Poco::Mutex::ScopedLock lock(session_m_); - - Poco::Data::Statement select(*session_); - select << - "SELECT local_id, uid, " - "experiment_id, key, value " - "FROM obm_actions " - "WHERE uid = :uid ", - useRef(UID); - error err = last_error("loadObmActions"); - if (err != noError) { - return err; - } - Poco::Data::RecordSet rs(select); - while (!select.done()) { - select.execute(); - bool more = rs.moveFirst(); - while (more) { - auto model = list.create(); - model->SetLocalID(rs[0].convert()); - model->SetUID(rs[1].convert()); - model->SetExperimentID(rs[2].convert()); - model->SetKey(rs[3].convert()); - model->SetValue(rs[4].convert()); - model->ClearDirty(); - - more = rs.moveNext(); - } - } - } catch(const Poco::Exception& exc) { - return exc.displayText(); - } catch(const std::exception& ex) { - return ex.what(); - } catch(const std::string & ex) { - return ex; - } - return last_error("loadObmActions"); -} - -error Database::loadObmExperiments(const Poco::UInt64 &UID, - ProtectedContainer &list) { - - if (!UID) { - return error("Cannot load OBM experiments without an user ID"); - } - - try { - list.clear(); - - Poco::Mutex::ScopedLock lock(session_m_); - - Poco::Data::Statement select(*session_); - select << - "SELECT local_id, uid, " - "nr, included, has_seen, actions " - "FROM obm_experiments " - "WHERE uid = :uid ", - useRef(UID); - error err = last_error("loadObmExperiments"); - if (err != noError) { - return err; - } - Poco::Data::RecordSet rs(select); - while (!select.done()) { - select.execute(); - bool more = rs.moveFirst(); - while (more) { - auto model = list.create(); - model->SetLocalID(rs[0].convert()); - model->SetUID(rs[1].convert()); - model->SetNr(rs[2].convert()); - model->SetIncluded(rs[3].convert()); - model->SetHasSeen(rs[4].convert()); - model->SetActions(rs[5].convert()); - model->ClearDirty(); - - more = rs.moveNext(); - } - } - } catch(const Poco::Exception& exc) { - return exc.displayText(); - } catch(const std::exception& ex) { - return ex.what(); - } catch(const std::string & ex) { - return ex; - } - return last_error("loadObmExperiments"); -} - -error Database::loadTimelineEvents(const Poco::UInt64 &UID, - ProtectedContainer &list) { - - if (!UID) { - return error("Cannot load user timeline without an user ID"); - } - - try { - list.clear(); - - Poco::Mutex::ScopedLock lock(session_m_); - - Poco::Data::Statement select(*session_); - select << - "SELECT local_id, title, filename, " - "start_time, end_time, idle, " - "uploaded, chunked, guid " - "FROM timeline_events " - "WHERE uid = :uid", - useRef(UID); - error err = last_error("loadTimelineEvents"); - if (err != noError) { - return err; - } - Poco::Data::RecordSet rs(select); - while (!select.done()) { - select.execute(); - bool more = rs.moveFirst(); - while (more) { - auto model = list.create(); - model->SetLocalID(rs[0].convert()); - if (!rs[1].isEmpty()) { - model->SetTitle(rs[1].convert()); - } - if (!rs[2].isEmpty()) { - model->SetFilename(rs[2].convert()); - } - model->SetStart(rs[3].convert()); - if (!rs[4].isEmpty()) { - model->SetEndTime(rs[4].convert()); - } - model->SetIdle(rs[5].convert()); - model->SetUploaded(rs[6].convert()); - model->SetChunked(rs[7].convert()); - model->SetGUID(rs[8].convert()); - - model->SetUID(UID); - - model->ClearDirty(); - - more = rs.moveNext(); - } - } - - // Ensure all timeline events have a GUID. - for (auto model : list) { - model->EnsureGUID(); - } - } catch(const Poco::Exception& exc) { - return exc.displayText(); - } catch(const std::exception& ex) { - return ex.what(); - } catch(const std::string & ex) { - return ex; - } - return noError; -} - -error Database::loadTimeEntries(const Poco::UInt64 &UID, - ProtectedContainer &list) { - - if (!UID) { - return error("Cannot load user time entries without an user ID"); - } - - try { - list.clear(); - - Poco::Mutex::ScopedLock lock(session_m_); - - Poco::Data::Statement select(*session_); - select << - "SELECT local_id, id, uid, description, wid, guid, pid, " - "tid, billable, duronly, ui_modified_at, start, stop, " - "duration, tags, created_with, deleted_at, updated_at, " - "project_guid, validation_error " - "FROM time_entries " - "WHERE uid = :uid " - "ORDER BY start DESC", - useRef(UID); - error err = last_error("loadTimeEntries"); - if (err != noError) { - return err; - } - err = loadTimeEntriesFromSQLStatement(&select, list); - if (err != noError) { - return err; - } - - // Ensure all time entries have a GUID. - for (auto te : list) { - te->EnsureGUID(); - if (te->Dirty()) { - te->SetUIModified(); - } - } - } catch(const Poco::Exception& exc) { - return exc.displayText(); - } catch(const std::exception& ex) { - return ex.what(); - } catch(const std::string & ex) { - return ex; - } - return noError; -} - -error Database::loadTimeEntriesFromSQLStatement(Poco::Data::Statement *select, - ProtectedContainer &list) { - - poco_check_ptr(select); - - try { - Poco::Data::RecordSet rs(*select); - while (!select->done()) { - select->execute(); - bool more = rs.moveFirst(); - while (more) { - auto model = list.create(); - model->SetLocalID(rs[0].convert()); - if (rs[1].isEmpty()) { - model->SetID(0); - } else { - model->SetID(rs[1].convert()); - } - model->SetUID(rs[2].convert()); - if (rs[3].isEmpty()) { - model->SetDescription(""); - } else { - model->SetDescription(rs[3].convert()); - } - model->SetWID(rs[4].convert()); - model->SetGUID(rs[5].convert()); - if (rs[6].isEmpty()) { - model->SetPID(0); - } else { - model->SetPID(rs[6].convert()); - } - if (rs[7].isEmpty()) { - model->SetTID(0); - } else { - model->SetTID(rs[7].convert()); - } - model->SetBillable(rs[8].convert()); - model->SetDurOnly(rs[9].convert()); - if (rs[10].isEmpty()) { - model->SetUIModifiedAt(0); - } else { - model->SetUIModifiedAt(rs[10].convert()); - } - model->SetStart(rs[11].convert()); - if (rs[12].isEmpty()) { - model->SetStop(0); - } else { - model->SetStop(rs[12].convert()); - } - model->SetDurationInSeconds(rs[13].convert()); - if (rs[14].isEmpty()) { - model->SetTags(""); - } else { - model->SetTags(rs[14].convert()); - } - if (rs[15].isEmpty()) { - model->SetCreatedWith(""); - } else { - model->SetCreatedWith(rs[15].convert()); - } - if (rs[16].isEmpty()) { - model->SetDeletedAt(0); - } else { - model->SetDeletedAt(rs[16].convert()); - } - if (rs[17].isEmpty()) { - model->SetUpdatedAt(0); - } else { - model->SetUpdatedAt(rs[17].convert()); - } - if (rs[18].isEmpty()) { - model->SetProjectGUID(""); - } else { - model->SetProjectGUID(rs[18].convert()); - } - if (rs[19].isEmpty()) { - model->SetValidationError(""); - } else { - model->SetValidationError(rs[19].convert()); - } - model->ClearDirty(); - - more = rs.moveNext(); - } - } - } catch(const Poco::Exception& exc) { - return exc.displayText(); - } catch(const std::exception& ex) { - return ex.what(); - } catch(const std::string & ex) { - return ex; - } - return noError; -} - template error Database::saveRelatedModels(const Poco::UInt64 UID, const std::string &table_name, diff --git a/src/database/database.h b/src/database/database.h index d0117cae2e..cf6cf68d50 100644 --- a/src/database/database.h +++ b/src/database/database.h @@ -292,46 +292,10 @@ class TOGGL_INTERNAL_EXPORT Database { const Poco::UInt64 &UID, ProtectedContainer &list); - error loadClients( - const Poco::UInt64 &UID, - ProtectedContainer &list); - error loadProjects( const Poco::UInt64 &UID, ProtectedContainer &list); - error loadTasks( - const Poco::UInt64 &UID, - ProtectedContainer &list); - - error loadTags( - const Poco::UInt64 &UID, - ProtectedContainer &list); - - error loadAutotrackerRules( - const Poco::UInt64 &UID, - ProtectedContainer &list); - - error loadObmActions( - const Poco::UInt64 &UID, - ProtectedContainer &list); - - error loadObmExperiments( - const Poco::UInt64 &UID, - ProtectedContainer &list); - - error loadTimeEntries( - const Poco::UInt64 &UID, - ProtectedContainer &list); - - error loadTimelineEvents( - const Poco::UInt64 &UID, - ProtectedContainer &list); - - error loadTimeEntriesFromSQLStatement( - Poco::Data::Statement *select, - ProtectedContainer &list); - template error saveRelatedModels( const Poco::UInt64 UID, diff --git a/src/database/migrations.cc b/src/database/migrations.cc index eb46a7704e..06ba91d5ea 100644 --- a/src/database/migrations.cc +++ b/src/database/migrations.cc @@ -32,6 +32,8 @@ error Migrations::migrateObmActions() { if (err != noError) { return err; } + + return noError; } error Migrations::migrateObmExperiments() { @@ -121,8 +123,8 @@ error Migrations::migrateAutotracker() { err = db_->Migrate( "autotracker_settings.guid", - "ALTER TABLE autotracker_settings " - "ADD COLUMN guid VARCHAR;" + "ALTER TABLE autotracker_settings ADD COLUMN guid VARCHAR;" + "ALTER TABLE autotracker_settings ADD COLUMN id INTEGER;" "CREATE UNIQUE INDEX id_autotracker_settings_guid ON autotracker_settings (uid, guid);"); if (err != noError) { return err; @@ -571,6 +573,13 @@ error Migrations::migrateTimeline() { return err; } + err = db_->Migrate( + "timeline_events.id", + "ALTER TABLE timeline_events ADD COLUMN id INTEGER;"); + if (err != noError) { + return err; + } + return noError; } diff --git a/src/model/autotracker.h b/src/model/autotracker.h index 50ae5ae41b..abe09089e6 100644 --- a/src/model/autotracker.h +++ b/src/model/autotracker.h @@ -15,6 +15,30 @@ namespace toggl { class TOGGL_INTERNAL_EXPORT AutotrackerRule : public BaseModel { + inline static const std::string modelName{ kModelAutotrackerRule }; + inline static const Query query{ + Query::Table{"autotracker_settings"}, + Query::Columns { + { "term", true }, + { "pid", false }, + { "tid", true } + }, + Query::Join{}, + Query::OrderBy{"term"}, + &BaseModel::query + }; + AutotrackerRule(ProtectedBase *container, Poco::Data::RecordSet &rs) + : BaseModel(container, rs) + { + size_t ptr{ query.Offset() }; + load(rs, query.IsRequired(ptr), ptr, term_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, pid_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, tid_); + ptr++; + ClearDirty(); + } AutotrackerRule(ProtectedBase *container) : BaseModel(container) {} diff --git a/src/model/base_model.h b/src/model/base_model.h index 2cf43be709..e2dd81285a 100644 --- a/src/model/base_model.h +++ b/src/model/base_model.h @@ -129,10 +129,14 @@ class TOGGL_INTERNAL_EXPORT BaseModel { : container_(container) { size_t ptr { query.Offset() }; - load(rs, query.IsRequired(ptr), ptr++, local_id_); - load(rs, query.IsRequired(ptr), ptr++, id_); - load(rs, query.IsRequired(ptr), ptr++, uid_); - load(rs, query.IsRequired(ptr), ptr++, guid_); + load(rs, query.IsRequired(ptr), ptr, local_id_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, id_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, uid_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, guid_); + ptr++; ClearDirty(); } diff --git a/src/model/client.h b/src/model/client.h index bbd614ed02..ae324092c5 100644 --- a/src/model/client.h +++ b/src/model/client.h @@ -16,6 +16,27 @@ namespace toggl { class TOGGL_INTERNAL_EXPORT Client : public BaseModel { + inline static const std::string modelName{ kModelClient }; + inline static const Query query{ + Query::Table{"clients"}, + Query::Columns { + { "name", true }, + { "wid", true } + }, + Query::Join{}, + Query::OrderBy{"name"}, + &BaseModel::query + }; + Client(ProtectedBase *container, Poco::Data::RecordSet &rs) + : BaseModel(container, rs) + { + size_t ptr{ query.Offset() }; + load(rs, query.IsRequired(ptr), ptr, name_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, wid_); + ptr++; + ClearDirty(); + } Client(ProtectedBase *container) : BaseModel(container) {} diff --git a/src/model/obm_action.h b/src/model/obm_action.h index dbd96353bd..18abfb448c 100644 --- a/src/model/obm_action.h +++ b/src/model/obm_action.h @@ -14,6 +14,42 @@ namespace toggl { class TOGGL_INTERNAL_EXPORT ObmAction : public BaseModel { + inline static const std::string modelName{ kModelObmAction }; + inline static const Query query{ + Query::Table{"obm_actions"}, + Query::Columns { + { "local_id", true }, + { "guid", false }, + { "experiment_id", true }, + { "key", true }, + { "value", true } + }, + Query::Join{}, + Query::OrderBy{}, + // doesn't actually use stuff from BaseModel + nullptr + }; + ObmAction(ProtectedBase *container, Poco::Data::RecordSet &rs) + : BaseModel(container, rs) + { + size_t ptr{ query.Offset() }; + // hacky + Poco::Int64 localId; + load(rs, query.IsRequired(ptr), ptr, localId); + SetLocalID(localId); + ptr++; + guid uuid; + load(rs, query.IsRequired(ptr), ptr, uuid); + SetGUID(uuid); + ptr++; + load(rs, query.IsRequired(ptr), ptr, experiment_id_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, key_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, value_); + ptr++; + ClearDirty(); + } ObmAction(ProtectedBase *container) : BaseModel(container) {} @@ -48,6 +84,45 @@ class TOGGL_INTERNAL_EXPORT ObmAction : public BaseModel { }; class TOGGL_INTERNAL_EXPORT ObmExperiment : public BaseModel { + inline static const std::string modelName{ kModelObmExperiment }; + inline static const Query query{ + Query::Table{"obm_experiments"}, + Query::Columns { + { "local_id", true }, + { "guid", false }, + { "nr", true }, + { "included", true }, + { "has_seen", true }, + { "actions", true } + }, + Query::Join{}, + Query::OrderBy{}, + // doesn't actually use stuff from BaseModel + nullptr + }; + ObmExperiment(ProtectedBase *container, Poco::Data::RecordSet &rs) + : BaseModel(container, rs) + { + size_t ptr{ query.Offset() }; + // hacky + Poco::Int64 localId; + load(rs, query.IsRequired(ptr), ptr, localId); + SetLocalID(localId); + ptr++; + guid uuid; + load(rs, query.IsRequired(ptr), ptr, uuid); + SetGUID(uuid); + ptr++; + load(rs, query.IsRequired(ptr), ptr, nr_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, included_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, has_seen_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, actions_); + ptr++; + ClearDirty(); + } ObmExperiment(ProtectedBase *container) : BaseModel(container) {} diff --git a/src/model/tag.h b/src/model/tag.h index 3d7864ef56..a8d6209998 100644 --- a/src/model/tag.h +++ b/src/model/tag.h @@ -12,6 +12,27 @@ namespace toggl { class TOGGL_INTERNAL_EXPORT Tag : public BaseModel { + inline static const std::string modelName{ kModelTag }; + inline static const Query query{ + Query::Table{"tags"}, + Query::Columns { + { "name", true }, + { "wid", true } + }, + Query::Join{}, + Query::OrderBy{"name"}, + &BaseModel::query + }; + Tag(ProtectedBase *container, Poco::Data::RecordSet &rs) + : BaseModel(container, rs) + { + size_t ptr{ query.Offset() }; + load(rs, query.IsRequired(ptr), ptr, name_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, wid_); + ptr++; + ClearDirty(); + } Tag(ProtectedBase *container) : BaseModel(container) {} diff --git a/src/model/task.h b/src/model/task.h index 351fdb33f8..0764fba6b4 100644 --- a/src/model/task.h +++ b/src/model/task.h @@ -14,6 +14,33 @@ namespace toggl { class TOGGL_INTERNAL_EXPORT Task : public BaseModel { + inline static const std::string modelName{ kModelTask }; + inline static const Query query{ + Query::Table{"tasks"}, + Query::Columns { + { "name", true }, + { "wid", true }, + { "pid", false }, + { "active", true } + }, + Query::Join{}, + Query::OrderBy{"name"}, + &BaseModel::query + }; + Task(ProtectedBase *container, Poco::Data::RecordSet &rs) + : BaseModel(container, rs) + { + size_t ptr{ query.Offset() }; + load(rs, query.IsRequired(ptr), ptr, name_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, wid_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, pid_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, active_); + ptr++; + ClearDirty(); + } Task(ProtectedBase *container) : BaseModel(container) {} diff --git a/src/model/time_entry.h b/src/model/time_entry.h index 3bf66ff9af..ef04e27e0d 100644 --- a/src/model/time_entry.h +++ b/src/model/time_entry.h @@ -15,6 +15,87 @@ namespace toggl { class TOGGL_INTERNAL_EXPORT TimeEntry : public BaseModel, public TimedEvent { + inline static const std::string modelName{ kModelTimeEntry }; + inline static const Query query{ + Query::Table{"time_entries"}, + Query::Columns { + { "description", false }, + { "wid", true }, + { "pid", false }, + { "tid", false }, + { "billable", true }, + { "duronly", true }, + { "ui_modified_at", false }, + { "start", true }, + { "stop", false }, + { "duration", true }, + { "tags", false }, + { "created_with", false }, + { "deleted_at", false }, + { "updated_at", false }, + { "project_guid", false }, + { "validation_error", false } + }, + Query::Join{}, + Query::OrderBy{"start DESC"}, + &BaseModel::query + }; + TimeEntry(ProtectedBase *container, Poco::Data::RecordSet &rs) + : BaseModel(container, rs) + { + size_t ptr{ query.Offset() }; + load(rs, query.IsRequired(ptr), ptr, description_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, wid_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, pid_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, tid_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, billable_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, duronly_); + ptr++; + // HACKS AHEAD + Poco::Int64 modifiedAt; + load(rs, query.IsRequired(ptr), ptr, modifiedAt); + SetUIModifiedAt(modifiedAt); + ptr++; + load(rs, query.IsRequired(ptr), ptr, start_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, stop_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, duration_in_seconds_); + ptr++; + // MORE HACKS + std::string tags; + load(rs, query.IsRequired(ptr), ptr, tags); + SetTags(tags); + ptr++; + load(rs, query.IsRequired(ptr), ptr, created_with_); + ptr++; + // HACK + Poco::Int64 deletedAt; + load(rs, query.IsRequired(ptr), ptr, deletedAt); + SetDeletedAt(deletedAt); + ptr++; + // HACK + Poco::Int64 updatedAt; + load(rs, query.IsRequired(ptr), ptr, updatedAt); + SetUpdatedAt(updatedAt); + ptr++; + load(rs, query.IsRequired(ptr), ptr, project_guid_); + ptr++; + error validationError; + load(rs, query.IsRequired(ptr), ptr, validationError); + SetValidationError(validationError); + ptr++; + + ClearDirty(); + EnsureGUID(); + if (Dirty()) + SetUIModified(); + } TimeEntry(ProtectedBase *container) : BaseModel(container) {} diff --git a/src/model/timeline_event.h b/src/model/timeline_event.h index b8b2a28984..9ba80c48af 100644 --- a/src/model/timeline_event.h +++ b/src/model/timeline_event.h @@ -15,6 +15,42 @@ namespace toggl { class TOGGL_INTERNAL_EXPORT TimelineEvent : public BaseModel, public TimedEvent { public: + inline static const std::string modelName{ kModelTimelineEvent }; + inline static const Query query{ + Query::Table{"timeline_events"}, + Query::Columns { + { "title", true }, + { "filename", true }, + { "start_time", true }, + { "end_time", true }, + { "idle", true }, + { "uploaded", true }, + { "chunked", true }, + }, + Query::Join{}, + Query::OrderBy{}, + &BaseModel::query + }; + TimelineEvent(ProtectedBase *container, Poco::Data::RecordSet &rs) + : BaseModel(container, rs) + { + size_t ptr{ query.Offset() }; + load(rs, query.IsRequired(ptr), ptr, title_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, filename_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, start_time_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, end_time_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, idle_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, uploaded_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, chunked_); + ptr++; + ClearDirty(); + } // public because instances get created all over the place TimelineEvent(ProtectedBase *container) : BaseModel(container) diff --git a/src/model/workspace.h b/src/model/workspace.h index ef1e3482f6..022aafcc0f 100644 --- a/src/model/workspace.h +++ b/src/model/workspace.h @@ -32,13 +32,20 @@ class TOGGL_INTERNAL_EXPORT Workspace : public BaseModel { : BaseModel(container, rs) { size_t ptr{ query.Offset() }; - load(rs, query.IsRequired(ptr), ptr++, name_); - load(rs, query.IsRequired(ptr), ptr++, premium_); - load(rs, query.IsRequired(ptr), ptr++, only_admins_may_create_projects_); - load(rs, query.IsRequired(ptr), ptr++, admin_); - load(rs, query.IsRequired(ptr), ptr++, projects_billable_by_default_); - load(rs, query.IsRequired(ptr), ptr++, business_); - load(rs, query.IsRequired(ptr), ptr++, locked_time_); + load(rs, query.IsRequired(ptr), ptr, name_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, premium_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, only_admins_may_create_projects_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, admin_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, projects_billable_by_default_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, business_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, locked_time_); + ptr++; ClearDirty(); } Workspace(ProtectedBase* container) From b38cae0cd4b3c3a7d53b7f8ba9ff10c82a102f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C5=99=C3=ADza?= Date: Mon, 30 Mar 2020 19:15:30 +0200 Subject: [PATCH 11/17] Port projects to the new way of construction as well (lib) --- src/database/database.cc | 89 +--------------------------------------- src/database/database.h | 4 -- src/model/project.h | 47 ++++++++++++++++++++- 3 files changed, 47 insertions(+), 93 deletions(-) diff --git a/src/database/database.cc b/src/database/database.cc index 4928f6e66c..de0b8eb913 100644 --- a/src/database/database.cc +++ b/src/database/database.cc @@ -1117,7 +1117,7 @@ error Database::loadUsersRelatedData(locked &user) { return err; } - err = loadProjects(user->ID(), user->GetRelatedData()->Projects); + err = loadModels(user->ID(), user->GetRelatedData()->Projects); if (err != noError) { return err; } @@ -1259,93 +1259,6 @@ error Database::LoadUserByID( return noError; } -error Database::loadProjects(const Poco::UInt64 &UID, - ProtectedContainer &list) { - - if (!UID) { - return error("Cannot load user projects without an user ID"); - } - - try { - list.clear(); - - Poco::Mutex::ScopedLock lock(session_m_); - - Poco::Data::Statement select(*session_); - select << - "SELECT projects.local_id, projects.id, projects.uid, " - "projects.name, projects.guid, projects.wid, projects.color, projects.cid, " - "projects.active, projects.billable, projects.client_guid, " - "clients.name as client_name " - "FROM projects " - "LEFT JOIN clients on projects.cid = clients.id " - "LEFT JOIN workspaces on projects.wid = workspaces.id " - "WHERE projects.uid = :uid " - "ORDER BY workspaces.name COLLATE NOCASE ASC," - "client_name COLLATE NOCASE ASC," - "projects.name COLLATE NOCASE ASC;", - useRef(UID); - error err = last_error("loadProjects"); - if (err != noError) { - return err; - } - Poco::Data::RecordSet rs(select); - while (!select.done()) { - select.execute(); - bool more = rs.moveFirst(); - while (more) { - auto model = list.create(); - model->SetLocalID(rs[0].convert()); - if (rs[1].isEmpty()) { - model->SetID(0); - } else { - model->SetID(rs[1].convert()); - } - model->SetUID(rs[2].convert()); - model->SetName(rs[3].convert()); - if (rs[4].isEmpty()) { - model->SetGUID(""); - } else { - model->SetGUID(rs[4].convert()); - } - model->SetWID(rs[5].convert()); - if (rs[6].isEmpty()) { - model->SetColor(""); - } else { - model->SetColor(rs[6].convert()); - } - if (rs[7].isEmpty()) { - model->SetCID(0); - } else { - model->SetCID(rs[7].convert()); - } - model->SetActive(rs[8].convert()); - model->SetBillable(rs[9].convert()); - if (rs[10].isEmpty()) { - model->SetClientGUID(""); - } else { - model->SetClientGUID(rs[10].convert()); - } - if (rs[11].isEmpty()) { - model->SetClientName(""); - } else { - model->SetClientName(rs[11].convert()); - } - model->ClearDirty(); - - more = rs.moveNext(); - } - } - } catch(const Poco::Exception& exc) { - return exc.displayText(); - } catch(const std::exception& ex) { - return ex.what(); - } catch(const std::string & ex) { - return ex; - } - return last_error("loadProjects"); -} - template error Database::saveRelatedModels(const Poco::UInt64 UID, const std::string &table_name, diff --git a/src/database/database.h b/src/database/database.h index cf6cf68d50..1f5ac98bd6 100644 --- a/src/database/database.h +++ b/src/database/database.h @@ -292,10 +292,6 @@ class TOGGL_INTERNAL_EXPORT Database { const Poco::UInt64 &UID, ProtectedContainer &list); - error loadProjects( - const Poco::UInt64 &UID, - ProtectedContainer &list); - template error saveRelatedModels( const Poco::UInt64 UID, diff --git a/src/model/project.h b/src/model/project.h index 33f26e5b76..8fdd3cbd61 100644 --- a/src/model/project.h +++ b/src/model/project.h @@ -14,7 +14,52 @@ namespace toggl { class TOGGL_INTERNAL_EXPORT Project : public BaseModel { - public: + inline static const std::string modelName{ kModelProject }; + inline static const Query query{ + Query::Table{"projects"}, + Query::Columns { + { "name", true }, + { "wid", true }, + { "color", false }, + { "cid", false }, + { "active", true }, + { "billable", true }, + { "client_guid", false }, + { "clients.name", false } + }, + Query::Join{ + "LEFT JOIN clients ON projects.cid = clients.id", + "LEFT JOIN workspaces ON projects.wid = workspaces.id" + }, + Query::OrderBy{ + "workspaces.name COLLATE NOCASE ASC", + "clients.name COLLATE NOCASE ASC", + "projects.name COLLATE NOCASE ASC" + }, + &BaseModel::query + }; + Project(ProtectedBase *container, Poco::Data::RecordSet &rs) + : BaseModel(container, rs) + { + size_t ptr{ query.Offset() }; + load(rs, query.IsRequired(ptr), ptr, name_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, wid_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, color_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, cid_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, active_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, billable_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, client_guid_); + ptr++; + load(rs, query.IsRequired(ptr), ptr, client_name_); + ptr++; + ClearDirty(); + } Project(ProtectedBase *container) : BaseModel(container) {} From 9737ca5ece24608812bc18d935e6b2440c29d3a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C5=99=C3=ADza?= Date: Tue, 31 Mar 2020 09:24:22 +0200 Subject: [PATCH 12/17] Attempt fixing build errors (actions) --- .github/workflows/main.yml | 47 ++++++++++++------- .../TogglDesktopDLL/TogglDesktopDLL.vcxproj | 8 +++- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ec4d06355e..348a87d4b3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,8 +21,8 @@ jobs: security default-keychain -s ~/Library/Keychains/build.keychain # Mac Developer Certificate - base64 -D <<< "${{ secrets.CERT_MACOS_DEVELOPMENT }}" > Bundle_cert_macos_development.p12 - security import ./Bundle_cert_macos_development.p12 -k ~/Library/Keychains/build.keychain -P ${{ secrets.CERT_MACOS_DEVELOPMENT_PASSWORD }} -T /usr/bin/codesign + base64 -D <<< "${{ secrets.CERT_MACOS_DEVELOPER }}" > Bundle_cert_macos_developer.p12 + security import ./Bundle_cert_macos_developer.p12 -k ~/Library/Keychains/build.keychain -P ${{ secrets.CERT_MACOS_DEVELOPER_PASSWORD }} -T /usr/bin/codesign # Application Certificate base64 -D <<< "${{ secrets.CERT_MACOS_APPLICATION }}" > Bundle_cert_macos_distribution.p12 @@ -79,9 +79,12 @@ jobs: fetch-depth: 1 - name: Install dependencies run: | - sudo apt update - sudo apt install libxss1 libgstreamer-plugins-base1.0-0 libgstreamer1.0-0 qt5-default libqt5gui5 libqt5webengine5 libqt5webenginecore5 libqt5webenginewidgets5 libqt5printsupport5 libqt5quickwidgets5 libqt5x11extras5 libxss1 - sudo apt install patchelf binutils cmake pkg-config qtbase5-dev qtwebengine5-dev libqt5x11extras5-dev qtbase5-private-dev libssl-dev libxss-dev libxmu-dev + # try getting the deps 10 times before solving this right + for i in {1..10}; do + sudo apt update + sudo apt install libxss1 libgstreamer-plugins-base1.0-0 libgstreamer1.0-0 qt5-default libqt5gui5 libqt5webengine5 libqt5webenginecore5 libqt5webenginewidgets5 libqt5printsupport5 libqt5quickwidgets5 libqt5x11extras5 libxss1 + sudo apt install patchelf binutils cmake pkg-config qtbase5-dev qtwebengine5-dev libqt5x11extras5-dev qtbase5-private-dev libssl-dev libxss-dev libxmu-dev + done - name: Build the Linux binary run: | bash ./dist/linux/package.sh build @@ -99,10 +102,13 @@ jobs: fetch-depth: 1 - name: Install dependencies run: | - sudo apt update - sudo apt install libxss1 libgstreamer-plugins-base1.0-0 libgstreamer1.0-0 - sudo apt install patchelf binutils cmake pkg-config libssl-dev libxss-dev libxmu-dev - sudo apt install dbus libfreetype6 fontconfig libx11-6 libx11-xcb1 libgl1-mesa-dev libnss3 libasound2 libxcomposite1 libxcursor1 libxi6 libxtst6 wget + # try getting the deps 10 times before solving this right + for i in {1..10}; do + sudo apt update + sudo apt install libxss1 libgstreamer-plugins-base1.0-0 libgstreamer1.0-0 + sudo apt install patchelf binutils cmake pkg-config libssl-dev libxss-dev libxmu-dev + sudo apt install dbus libfreetype6 fontconfig libx11-6 libx11-xcb1 libgl1-mesa-dev libnss3 libasound2 libxcomposite1 libxcursor1 libxi6 libxtst6 wget + done - name: Fetch and install binary Qt run: | bash ./dist/linux/install-qt.sh 5.12.5 @@ -131,8 +137,11 @@ jobs: gpg --import <<< "${{ secrets.CERT_LINUX_DEB64 }}" - name: Install dependencies run: | - sudo apt update - sudo apt install devscripts cmake debhelper pkg-config qtbase5-dev qtwebengine5-dev libqt5x11extras5-dev qtbase5-private-dev libssl-dev libxss-dev libxmu-dev + # try getting the deps 10 times before solving this right + for i in {1..10}; do + sudo apt update + sudo apt install devscripts cmake debhelper pkg-config qtbase5-dev qtwebengine5-dev libqt5x11extras5-dev qtbase5-private-dev libssl-dev libxss-dev libxmu-dev + done - name: Build a Debian package run: | TAG_NAME=$(./dist/get-tag-name.sh) @@ -156,13 +165,19 @@ jobs: fetch-depth: 1 - name: Install Flatpak run: | - sudo apt update - sudo apt install flatpak flatpak-builder + # try getting the deps 10 times before solving this right + for i in {1..10}; do + sudo apt update + sudo apt install flatpak flatpak-builder + done - name: Install Flatpak KDE SDK run: | - sudo flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo - sudo flatpak install --system -y flathub org.kde.Platform//5.12 - sudo flatpak install --system -y flathub org.kde.Sdk//5.12 + # try getting the deps 10 times before solving this right + for i in {1..10}; do + sudo flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo + sudo flatpak install --system -y flathub org.kde.Platform//5.12 + sudo flatpak install --system -y flathub org.kde.Sdk//5.12 + done - name: Build Linux Flatpak package - KDE based run: | pushd dist/linux/flatpak diff --git a/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj b/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj index f57b623e18..f9a26740e6 100644 --- a/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj +++ b/src/lib/windows/TogglDesktopDLL/TogglDesktopDLL.vcxproj @@ -172,21 +172,25 @@ false false false + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\..\.. false false false + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\..\.. false false false + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\..\.. false false false + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\..\.. true @@ -198,6 +202,7 @@ true false false + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\..\.. true @@ -209,6 +214,7 @@ true false false + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\..\.. @@ -672,4 +678,4 @@ - \ No newline at end of file + From 5922726bc0375a9c6bd8372869c90e0575d90dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C5=99=C3=ADza?= Date: Tue, 31 Mar 2020 10:09:38 +0200 Subject: [PATCH 13/17] Specify the full defaultComparison type to fix macOS build (lib) --- src/util/memory.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/memory.h b/src/util/memory.h index a4575c1637..ef8b32cf05 100644 --- a/src/util/memory.h +++ b/src/util/memory.h @@ -243,7 +243,7 @@ class ProtectedContainer : public ProtectedBase { friend class iterator; friend class const_iterator; - static inline std::function defaultComparison{ + static inline comparison_function defaultComparison { [](const T* l, const T* r) { return l < r; } }; /** From 364d89bd2aab252aa596d0337fe8090c7ef73d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C5=99=C3=ADza?= Date: Tue, 31 Mar 2020 11:31:53 +0200 Subject: [PATCH 14/17] Fix library paths (osx) --- src/lib/osx/TogglDesktopLibrary.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/osx/TogglDesktopLibrary.xcodeproj/project.pbxproj b/src/lib/osx/TogglDesktopLibrary.xcodeproj/project.pbxproj index 4c98ffb97f..013a4ee5c2 100644 --- a/src/lib/osx/TogglDesktopLibrary.xcodeproj/project.pbxproj +++ b/src/lib/osx/TogglDesktopLibrary.xcodeproj/project.pbxproj @@ -191,8 +191,8 @@ B81AC300242AB290005FA63D /* database.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = database.h; path = ../../../database/database.h; sourceTree = ""; }; B81AC301242AB290005FA63D /* migrations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = migrations.h; path = ../../../database/migrations.h; sourceTree = ""; }; B81AC302242AB290005FA63D /* migrations.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = migrations.cc; path = ../../../database/migrations.cc; sourceTree = ""; }; - B81AC307242AB3A3005FA63D /* logger.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = logger.cc; sourceTree = ""; }; - B81AC308242AB3A3005FA63D /* logger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = logger.h; sourceTree = ""; }; + B81AC307242AB3A3005FA63D /* logger.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = logger.cc; path = ../../../util/logger.cc; sourceTree = ""; }; + B81AC308242AB3A3005FA63D /* logger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = logger.h; path = ../../../util/logger.h; sourceTree = ""; }; B81EB946240EAB1500786DF0 /* memory.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = memory.cc; path = ../../../util/memory.cc; sourceTree = ""; }; B81EB947240EAB1500786DF0 /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = memory.h; path = ../../../util/memory.h; sourceTree = ""; }; BA1AB53D235DEAD4000433AE /* MacOSVersionChecker.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MacOSVersionChecker.mm; sourceTree = ""; }; From e4220175a3703f9a67fdea5eba04fb419573e7a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C5=99=C3=ADza?= Date: Tue, 31 Mar 2020 11:48:49 +0200 Subject: [PATCH 15/17] Ignore dependency install errors on Linux and try 10 times (actions) ... No comment --- .github/workflows/main.yml | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 348a87d4b3..20880967d7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -81,9 +81,8 @@ jobs: run: | # try getting the deps 10 times before solving this right for i in {1..10}; do - sudo apt update - sudo apt install libxss1 libgstreamer-plugins-base1.0-0 libgstreamer1.0-0 qt5-default libqt5gui5 libqt5webengine5 libqt5webenginecore5 libqt5webenginewidgets5 libqt5printsupport5 libqt5quickwidgets5 libqt5x11extras5 libxss1 - sudo apt install patchelf binutils cmake pkg-config qtbase5-dev qtwebengine5-dev libqt5x11extras5-dev qtbase5-private-dev libssl-dev libxss-dev libxmu-dev + sudo apt update || true + sudo apt install libxss1 libgstreamer-plugins-base1.0-0 libgstreamer1.0-0 qt5-default libqt5gui5 libqt5webengine5 libqt5webenginecore5 libqt5webenginewidgets5 libqt5printsupport5 libqt5quickwidgets5 libqt5x11extras5 libxss1 patchelf binutils cmake pkg-config qtbase5-dev qtwebengine5-dev libqt5x11extras5-dev qtbase5-private-dev libssl-dev libxss-dev libxmu-dev || true done - name: Build the Linux binary run: | @@ -104,10 +103,8 @@ jobs: run: | # try getting the deps 10 times before solving this right for i in {1..10}; do - sudo apt update - sudo apt install libxss1 libgstreamer-plugins-base1.0-0 libgstreamer1.0-0 - sudo apt install patchelf binutils cmake pkg-config libssl-dev libxss-dev libxmu-dev - sudo apt install dbus libfreetype6 fontconfig libx11-6 libx11-xcb1 libgl1-mesa-dev libnss3 libasound2 libxcomposite1 libxcursor1 libxi6 libxtst6 wget + sudo apt update || true + sudo apt install libxss1 libgstreamer-plugins-base1.0-0 libgstreamer1.0-0 patchelf binutils cmake pkg-config libssl-dev libxss-dev libxmu-dev dbus libfreetype6 fontconfig libx11-6 libx11-xcb1 libgl1-mesa-dev libnss3 libasound2 libxcomposite1 libxcursor1 libxi6 libxtst6 wget || true done - name: Fetch and install binary Qt run: | @@ -139,8 +136,8 @@ jobs: run: | # try getting the deps 10 times before solving this right for i in {1..10}; do - sudo apt update - sudo apt install devscripts cmake debhelper pkg-config qtbase5-dev qtwebengine5-dev libqt5x11extras5-dev qtbase5-private-dev libssl-dev libxss-dev libxmu-dev + sudo apt update || true + sudo apt install devscripts cmake debhelper pkg-config qtbase5-dev qtwebengine5-dev libqt5x11extras5-dev qtbase5-private-dev libssl-dev libxss-dev libxmu-dev || true done - name: Build a Debian package run: | @@ -167,16 +164,16 @@ jobs: run: | # try getting the deps 10 times before solving this right for i in {1..10}; do - sudo apt update - sudo apt install flatpak flatpak-builder + sudo apt update || true + sudo apt install flatpak flatpak-builder || true done - name: Install Flatpak KDE SDK run: | # try getting the deps 10 times before solving this right for i in {1..10}; do - sudo flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo - sudo flatpak install --system -y flathub org.kde.Platform//5.12 - sudo flatpak install --system -y flathub org.kde.Sdk//5.12 + sudo flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo || true + sudo flatpak install --system -y flathub org.kde.Platform//5.12 || true + sudo flatpak install --system -y flathub org.kde.Sdk//5.12 || true done - name: Build Linux Flatpak package - KDE based run: | From 78cdc8e95f15d5cfbc532a0556c5aa466cab19ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C5=99=C3=ADza?= Date: Tue, 31 Mar 2020 12:11:57 +0200 Subject: [PATCH 16/17] Another attempt to fix build (osx) --- src/lib/osx/TogglDesktopLibrary.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/osx/TogglDesktopLibrary.xcodeproj/project.pbxproj b/src/lib/osx/TogglDesktopLibrary.xcodeproj/project.pbxproj index 013a4ee5c2..ebb584639f 100644 --- a/src/lib/osx/TogglDesktopLibrary.xcodeproj/project.pbxproj +++ b/src/lib/osx/TogglDesktopLibrary.xcodeproj/project.pbxproj @@ -191,8 +191,8 @@ B81AC300242AB290005FA63D /* database.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = database.h; path = ../../../database/database.h; sourceTree = ""; }; B81AC301242AB290005FA63D /* migrations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = migrations.h; path = ../../../database/migrations.h; sourceTree = ""; }; B81AC302242AB290005FA63D /* migrations.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = migrations.cc; path = ../../../database/migrations.cc; sourceTree = ""; }; - B81AC307242AB3A3005FA63D /* logger.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = logger.cc; path = ../../../util/logger.cc; sourceTree = ""; }; - B81AC308242AB3A3005FA63D /* logger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = logger.h; path = ../../../util/logger.h; sourceTree = ""; }; + B81AC307242AB3A3005FA63D /* logger.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = logger.cc; path = ../../../../util/logger.cc; sourceTree = ""; }; + B81AC308242AB3A3005FA63D /* logger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = logger.h; path = ../../../../util/logger.h; sourceTree = ""; }; B81EB946240EAB1500786DF0 /* memory.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = memory.cc; path = ../../../util/memory.cc; sourceTree = ""; }; B81EB947240EAB1500786DF0 /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = memory.h; path = ../../../util/memory.h; sourceTree = ""; }; BA1AB53D235DEAD4000433AE /* MacOSVersionChecker.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MacOSVersionChecker.mm; sourceTree = ""; }; From 3cc471767b2aea4b3752534bab186851b871a1eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C5=99=C3=ADza?= Date: Fri, 3 Apr 2020 17:13:23 +0200 Subject: [PATCH 17/17] Fix reversed condition in IsRequired (lib) --- src/model/base_model.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/model/base_model.h b/src/model/base_model.h index e2dd81285a..18847b1792 100644 --- a/src/model/base_model.h +++ b/src/model/base_model.h @@ -76,10 +76,10 @@ struct BaseModelQuery { } bool IsRequired(size_t idx) const { - if (parent_ && idx >= Offset()) { - return parent_->IsRequired(idx - Offset()); + if (!parent_ || idx >= Offset()) { + return columns_[idx - Offset()].required; } - return columns_[idx].required; + return parent_->IsRequired(idx); } /**