// DBSQLiteHandler.h
#import <Foundasion/Foundation.h>
#import <sqlite3.h>
@class DBSQLiteHandler;
@protocol DBSQLiteHandlerDelegate
- (void)handler:(DBSQLiteHandler *)handler didProcessRowAtIndex:(NSInteger)rowIndex;
@end
@interface DBSQLiteHandler : NSObject
@property (nonatomic, weak) id<DBSQLiteHandlerDelegate> delegate;
@property (nonatomic, asssign, readonly) sqlite3_stmt *preparedStatement;
- (instancetype)initWithDatabaseAtPath:(NSString *)dbPath;
- (void)assignQuery:(NSString *)queryString;
- (BOOL)compileQuery;
- (void)executeAndFetch;
- (void)finalizeOperations;
- (void)configureRandomResultsWithLimit:(NSInteger)limit;
- (void)configureResultRangeStartingAt:(NSInteger)offset count:(NSInteger)rowCount;
@end
// DBSQLiteHandler.m
#import "DBSQLiteHandler.h"
@implementation DBSQLiteHandler {
sqlite3 *_databaseConnection;
NSString *_currentQuery;
sqlite3_stmt *_compiledStatement;
NSInteger _processedRowCount;
}
@synthesize delegate = _delegate;
@synthesize preparedStatement = _compiledStatement;
- (instancetype)initWithDatabaseAtPath:(NSString *)dbPath {
self = [super init];
if (self) {
int openStatus = sqlite3_open([dbPath UTF8String], &_databaseConnection);
if (openStatus != SQLITE_OK) {
return nil;
}
}
return self;
}
- (void)dealloc {
[_currentQuery release];
sqlite3_close(_databaseConnection);
[super dealloc];
}
- (void)assignQuery:(NSString *)queryString {
if (_currentQuery != queryString) {
[_currentQuery release];
_currentQuery = [queryString copy];
}
}
- (BOOL)compileQuery {
return sqlite3_prepare_v2(_databaseConnection,
[_currentQuery UTF8String],
-1,
&_compiledStatement,
NULL) == SQLITE_OK;
}
- (void)executeAndFetch {
while (sqlite3_step(_compiledStatement) == SQLITE_ROW) {
_processedRowCount++;
[self.delegate handler:self didProcessRowAtIndex:_processedRowCount];
}
}
- (void)finalizeOperations {
sqlite3_finalize(_compiledStatement);
}
- (void)configureRandomResultsWithLimit:(NSInteger)limit {
NSString *randomClause = [NSString stringWithFormat:@" ORDER BY RANDOM() LIMIT %ld", (long)limit];
NSString *modifiedQuery = [_currentQuery stringByAppendingString:randomClause];
[self assignQuery:modifiedQuery];
}
- (void)configureResultRangeStartingAt:(NSInteger)offset count:(NSInteger)rowCount {
NSString *limitClause = [NSString stringWithFormat:@" LIMIT %ld,%ld", (long)offset, (long)rowCount];
NSString *updatedQuery = [_currentQuery stringByAppendingString:limitClause];
[self assignQuery:updatedQuery];
}
@end