From 2b85abcfae5fe3ffbe804293c54ce1dddb29f113 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Tue, 18 Nov 2025 21:20:20 -0500 Subject: [PATCH] Added sample scheduled job, cached repositories. --- finnow-api/source/app.d | 9 +++ finnow-api/source/profile/data_impl_sqlite.d | 76 +++++++++++++++----- 2 files changed, 66 insertions(+), 19 deletions(-) diff --git a/finnow-api/source/app.d b/finnow-api/source/app.d index 9aeeeb8..fd9d348 100644 --- a/finnow-api/source/app.d +++ b/finnow-api/source/app.d @@ -1,6 +1,8 @@ import handy_http_transport; import slf4d; import slf4d.default_provider; +import scheduled; +import std.datetime; import api_mapping; import util.config; @@ -12,6 +14,13 @@ void main() { configureLoggingProvider(provider); infoF!"Loaded app config: port = %d, webOrigin = %s"(config.port, config.webOrigin); + // Start scheduled tasks in a separate thread: + JobScheduler jobScheduler = new TaskPoolScheduler(); + jobScheduler.addJob(() { + info("Executing scheduled job with fixed interval."); + }, new FixedIntervalSchedule(minutes(1))); + jobScheduler.start(); + Http1TransportConfig transportConfig = defaultConfig(); transportConfig.port = config.port; HttpTransport transport = new TaskPoolHttp1Transport(mapApiHandlers(config.webOrigin), transportConfig); diff --git a/finnow-api/source/profile/data_impl_sqlite.d b/finnow-api/source/profile/data_impl_sqlite.d index 494e200..9363d55 100644 --- a/finnow-api/source/profile/data_impl_sqlite.d +++ b/finnow-api/source/profile/data_impl_sqlite.d @@ -152,6 +152,17 @@ class SqliteProfileDataSource : ProfileDataSource { private const string dbPath; Database db; + // Cached versions of all the repositories: + PropertiesRepository propertiesRepo; + AttachmentRepository attachmentRepo; + AccountRepository accountRepo; + AccountJournalEntryRepository accountJournalEntryRepo; + AccountValueRecordRepository accountValueRecordRepo; + TransactionVendorRepository transactionVendorRepo; + TransactionCategoryRepository transactionCategoryRepo; + TransactionTagRepository transactionTagRepo; + TransactionRepository transactionRepo; + this(string path) { this.dbPath = path; import std.file : exists; @@ -169,40 +180,67 @@ class SqliteProfileDataSource : ProfileDataSource { migrateSchema(); } - PropertiesRepository getPropertiesRepository() return scope { - return new SqlitePropertiesRepository(db); + PropertiesRepository getPropertiesRepository() { + if (propertiesRepo is null) { + propertiesRepo = new SqlitePropertiesRepository(db); + } + return propertiesRepo; } - AttachmentRepository getAttachmentRepository() return scope { - return new SqliteAttachmentRepository(db); + AttachmentRepository getAttachmentRepository() { + if (attachmentRepo is null) { + attachmentRepo = new SqliteAttachmentRepository(db); + } + return attachmentRepo; } - AccountRepository getAccountRepository() return scope { - return new SqliteAccountRepository(db); + AccountRepository getAccountRepository() { + if (accountRepo is null) { + accountRepo = new SqliteAccountRepository(db); + } + return accountRepo; } - AccountJournalEntryRepository getAccountJournalEntryRepository() return scope { - return new SqliteAccountJournalEntryRepository(db); + AccountJournalEntryRepository getAccountJournalEntryRepository() { + if (accountJournalEntryRepo is null) { + accountJournalEntryRepo = new SqliteAccountJournalEntryRepository(db); + } + return accountJournalEntryRepo; } - AccountValueRecordRepository getAccountValueRecordRepository() return scope { - return new SqliteAccountValueRecordRepository(db); + AccountValueRecordRepository getAccountValueRecordRepository() { + if (accountValueRecordRepo is null) { + accountValueRecordRepo = new SqliteAccountValueRecordRepository(db); + } + return accountValueRecordRepo; } - TransactionVendorRepository getTransactionVendorRepository() return scope { - return new SqliteTransactionVendorRepository(db); + TransactionVendorRepository getTransactionVendorRepository() { + if (transactionVendorRepo is null) { + transactionVendorRepo = new SqliteTransactionVendorRepository(db); + } + return transactionVendorRepo; } - TransactionCategoryRepository getTransactionCategoryRepository() return scope { - return new SqliteTransactionCategoryRepository(db); + TransactionCategoryRepository getTransactionCategoryRepository() { + if (transactionCategoryRepo is null) { + transactionCategoryRepo = new SqliteTransactionCategoryRepository(db); + } + return transactionCategoryRepo; } - TransactionTagRepository getTransactionTagRepository() return scope { - return new SqliteTransactionTagRepository(db); + TransactionTagRepository getTransactionTagRepository() { + if (transactionTagRepo is null) { + transactionTagRepo = new SqliteTransactionTagRepository(db); + } + return transactionTagRepo; } - TransactionRepository getTransactionRepository() return scope { - return new SqliteTransactionRepository(db); + TransactionRepository getTransactionRepository() { + if (transactionRepo is null) { + transactionRepo = new SqliteTransactionRepository(db); + } + return transactionRepo; } void doTransaction(void delegate () dg) { @@ -211,7 +249,7 @@ class SqliteProfileDataSource : ProfileDataSource { private void migrateSchema() { import std.conv; - PropertiesRepository propsRepo = new SqlitePropertiesRepository(this.db); + PropertiesRepository propsRepo = getPropertiesRepository(); uint currentVersion; try { currentVersion = propsRepo.findProperty("database-schema-version")