diff options
| author | Ruben Beltran del Rio <git@r.bdr.sh> | 2025-09-10 11:32:28 +0200 |
|---|---|---|
| committer | Ruben Beltran del Rio <git@r.bdr.sh> | 2025-09-10 11:32:28 +0200 |
| commit | c791858db3de3568f0ea2839c79b360a0dfb15ab (patch) | |
| tree | 7cf50c93cdf03075d10c14c8ad1f7a646b2a05c7 /QSThingsPlugin/Helpers | |
Initial commit
Diffstat (limited to 'QSThingsPlugin/Helpers')
| -rw-r--r-- | QSThingsPlugin/Helpers/SQLHelper.h | 16 | ||||
| -rw-r--r-- | QSThingsPlugin/Helpers/SQLHelper.m | 84 |
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 |