aboutsummaryrefslogtreecommitdiff
path: root/QSThingsPlugin/Helpers
diff options
context:
space:
mode:
authorRuben Beltran del Rio <git@r.bdr.sh>2025-09-10 11:32:28 +0200
committerRuben Beltran del Rio <git@r.bdr.sh>2025-09-10 11:32:28 +0200
commitc791858db3de3568f0ea2839c79b360a0dfb15ab (patch)
tree7cf50c93cdf03075d10c14c8ad1f7a646b2a05c7 /QSThingsPlugin/Helpers
Initial commit
Diffstat (limited to 'QSThingsPlugin/Helpers')
-rw-r--r--QSThingsPlugin/Helpers/SQLHelper.h16
-rw-r--r--QSThingsPlugin/Helpers/SQLHelper.m84
2 files changed, 100 insertions, 0 deletions
diff --git a/QSThingsPlugin/Helpers/SQLHelper.h b/QSThingsPlugin/Helpers/SQLHelper.h
new file mode 100644
index 0000000..fc63650
--- /dev/null
+++ b/QSThingsPlugin/Helpers/SQLHelper.h
@@ -0,0 +1,16 @@
+/**
+ Helper class to access the things sqlite database.
+ */
+@interface SQLHelper : NSObject
+{
+}
+
+/**
+ Execute an SQL query on the things database
+ @param query the SQL query. Must contain output fieldnames "url" and "title".
+ @param path file path to the database
+ @returns an array of Task objects. Will return empty if an error occurs.
+ */
++ (NSArray *) executeSql:(NSString *)query onFile:(NSString *)path;
+
+@end
diff --git a/QSThingsPlugin/Helpers/SQLHelper.m b/QSThingsPlugin/Helpers/SQLHelper.m
new file mode 100644
index 0000000..6d94bb5
--- /dev/null
+++ b/QSThingsPlugin/Helpers/SQLHelper.m
@@ -0,0 +1,84 @@
+#import "SQLHelper.h"
+#import <QSFoundation/FMDatabase.h>
+
+@implementation SQLHelper
+
++ (NSArray *) executeSql:(NSString *)query onFile:(NSString *)path {
+
+ NSMutableArray *objects = [NSMutableArray arrayWithCapacity:0];
+ NSFileManager *manager = [NSFileManager defaultManager];
+
+ FMDatabase *database = [FMDatabase databaseWithPath:path];
+ if (![database openWithFlags:0x00000001]) { // 1 = SQLITE_OPEN_READONLY
+ NSLog(@"Could not open Firefox's places.sqlite DB.");
+ return @[];
+ }
+ [database goodConnection];
+
+ // execute SQL query
+ FMResultSet *resultSet = [database executeQuery:query];
+ if ([database hadError]) {
+ NSLog(@"Error while reading Things database. (%d): %@", [database lastErrorCode], [database lastErrorMessage]);
+ return @[];
+ }
+
+ while ([resultSet next]) {
+ // Create a completely independent dictionary with string copies
+ NSMutableDictionary *resultDictionary = [NSMutableDictionary dictionary];
+
+ // Manually copy each field to ensure we have independent string objects
+ NSDictionary *originalDict = resultSet.resultDictionary;
+ for (NSString *key in originalDict.allKeys) {
+ id value = [originalDict objectForKey:key];
+ if (value && value != [NSNull null]) {
+ // Make sure we have independent copies of strings
+ if ([value isKindOfClass:[NSString class]]) {
+ resultDictionary[key] = [NSString stringWithString:value];
+ } else {
+ resultDictionary[key] = value;
+ }
+ }
+ }
+
+ [objects addObject:[resultDictionary copy]]; // Make immutable copy
+ }
+
+ [resultSet close];
+ [database close];
+
+ return objects;
+}
+
++ (BOOL)appendString:(NSString *)string toFile:(NSString *)filePath {
+ // Create file manager
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+
+ // Check if file exists, create it if it doesn't
+ if (![fileManager fileExistsAtPath:filePath]) {
+ // Create empty file
+ [@"" writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
+ }
+
+ // Create file handle for appending
+ NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];
+
+ if (!fileHandle) {
+ NSLog(@"Failed to open file for writing: %@", filePath);
+ return NO;
+ }
+
+ // Move to end of file
+ [fileHandle seekToEndOfFile];
+
+ // Convert string to data and write
+ NSData *stringData = [string dataUsingEncoding:NSUTF8StringEncoding];
+ [fileHandle writeData:stringData];
+
+ // Close file handle
+ [fileHandle closeFile];
+
+ NSLog(@"Successfully appended string to: %@", filePath);
+ return YES;
+}
+
+@end