9
9
#import " FLEXSQLiteDatabaseManager.h"
10
10
#import " FLEXManager.h"
11
11
#import " NSArray+Functional.h"
12
+ #import " FLEXSQLResult.h"
12
13
#import < sqlite3.h>
13
14
14
- static NSString * const QUERY_TABLENAMES_SQL = @" SELECT name FROM sqlite_master WHERE type='table' ORDER BY name" ;
15
+ static NSString * const QUERY_TABLENAMES = @" SELECT name FROM sqlite_master WHERE type='table' ORDER BY name" ;
15
16
16
17
@interface FLEXSQLiteDatabaseManager ()
17
- @property (nonatomic , readonly ) sqlite3 *db;
18
+ @property (nonatomic ) sqlite3 *db;
18
19
@property (nonatomic , copy ) NSString *path;
19
20
@end
20
21
@@ -36,7 +37,7 @@ - (instancetype)initWithPath:(NSString *)path {
36
37
}
37
38
38
39
- (BOOL )open {
39
- if (_db ) {
40
+ if (self. db ) {
40
41
return YES ;
41
42
}
42
43
@@ -57,9 +58,9 @@ - (BOOL)open {
57
58
58
59
return YES ;
59
60
}
60
-
61
+
61
62
- (BOOL )close {
62
- if (!_db ) {
63
+ if (!self. db ) {
63
64
return YES ;
64
65
}
65
66
@@ -84,88 +85,85 @@ - (BOOL)close {
84
85
}
85
86
} while (retry);
86
87
87
- _db = nil ;
88
+ self. db = nil ;
88
89
return YES ;
89
90
}
90
91
91
92
- (NSArray <NSString *> *)queryAllTables {
92
- return [[self executeQuery: QUERY_TABLENAMES_SQL] flex_mapped: ^id (NSArray *table, NSUInteger idx) {
93
+ return [[self executeStatement: QUERY_TABLENAMES].rows flex_mapped: ^id (NSArray *table, NSUInteger idx) {
93
94
return table.firstObject ;
94
95
}];
95
96
}
96
97
97
- - (NSArray <NSString *> *)queryAllColumnsWithTableName : (NSString *)tableName {
98
+ - (NSArray <NSString *> *)queryAllColumnsOfTable : (NSString *)tableName {
98
99
NSString *sql = [NSString stringWithFormat: @" PRAGMA table_info('%@ ')" ,tableName];
99
- NSArray < NSDictionary *> * results = [self executeQueryWithColumns : sql];
100
+ FLEXSQLResult * results = [self executeStatement : sql];
100
101
101
- return [results flex_mapped: ^id (NSDictionary *column, NSUInteger idx) {
102
+ return [results.keyedRows flex_mapped: ^id (NSDictionary *column, NSUInteger idx) {
102
103
return column[@" name" ];
103
104
}];
104
105
}
105
106
106
- - (NSArray <NSArray *> *)queryAllDataWithTableName : (NSString *)tableName {
107
- return [self executeQuery : [@" SELECT * FROM "
107
+ - (NSArray <NSArray *> *)queryAllDataInTable : (NSString *)tableName {
108
+ return [self executeStatement : [@" SELECT * FROM "
108
109
stringByAppendingString: tableName
109
- ]];
110
+ ]]. rows ;
110
111
}
111
112
112
- #pragma mark - Private
113
-
114
- // / @return an array of rows, where each row is an array
115
- // / containing the values of each column for that row
116
- - (NSArray <NSArray *> *)executeQuery : (NSString *)sql {
113
+ - (FLEXSQLResult *)executeStatement : (NSString *)sql {
117
114
[self open ];
118
115
119
- NSMutableArray < NSArray *> *results = [ NSMutableArray array ] ;
116
+ FLEXSQLResult *result = nil ;
120
117
121
118
sqlite3_stmt *pstmt;
122
119
if (sqlite3_prepare_v2 (_db, sql.UTF8String , -1 , &pstmt, 0 ) == SQLITE_OK) {
123
- while (sqlite3_step (pstmt) == SQLITE_ROW) {
124
- int num_cols = sqlite3_data_count (pstmt);
125
- if (num_cols > 0 ) {
126
- int columnCount = sqlite3_column_count (pstmt);
127
-
128
- [results addObject: [NSArray flex_forEachUpTo: columnCount map: ^id (NSUInteger i) {
120
+ NSMutableArray <NSArray *> *rows = [NSMutableArray new ];
121
+
122
+ // Grab columns
123
+ int columnCount = sqlite3_column_count (pstmt);
124
+ NSArray <NSString *> *columns = [NSArray flex_forEachUpTo: columnCount map: ^id (NSUInteger i) {
125
+ return @(sqlite3_column_name (pstmt, (int )i));
126
+ }];
127
+
128
+ // Execute statement
129
+ int status;
130
+ while ((status = sqlite3_step (pstmt)) == SQLITE_ROW) {
131
+ // Grab rows if this is a selection query
132
+ int dataCount = sqlite3_data_count (pstmt);
133
+ if (dataCount > 0 ) {
134
+ [rows addObject: [NSArray flex_forEachUpTo: columnCount map: ^id (NSUInteger i) {
129
135
return [self objectForColumnIndex: (int )i stmt: pstmt];
130
136
}]];
131
137
}
132
138
}
133
- }
134
-
135
- [self close ];
136
- return results;
137
- }
138
-
139
- // / Like \c executeQuery: except that a list of dictionaries are returned,
140
- // / where the keys are column names and the values are the data.
141
- - (NSArray <NSDictionary *> *)executeQueryWithColumns : (NSString *)sql {
142
- [self open ];
143
-
144
- NSMutableArray <NSDictionary *> *results = [NSMutableArray array ];
145
-
146
- sqlite3_stmt *pstmt;
147
- if (sqlite3_prepare_v2 (_db, sql.UTF8String , -1 , &pstmt, 0 ) == SQLITE_OK) {
148
- while (sqlite3_step (pstmt) == SQLITE_ROW) {
149
- int num_cols = sqlite3_data_count (pstmt);
150
- if (num_cols > 0 ) {
151
- int columnCount = sqlite3_column_count (pstmt);
152
-
153
-
154
- NSMutableDictionary *rowFields = [NSMutableDictionary new ];
155
- for (int i = 0 ; i < columnCount; i++) {
156
- id value = [self objectForColumnIndex: (int )i stmt: pstmt];
157
- rowFields[@(sqlite3_column_name (pstmt, i))] = value;
158
- }
159
-
160
- [results addObject: rowFields];
139
+
140
+ if (status == SQLITE_DONE) {
141
+ if (rows.count ) {
142
+ // We selected some rows
143
+ result = [FLEXSQLResult columns: columns rows: rows];
144
+ } else {
145
+ // We executed a query like INSERT, UDPATE, or DELETE
146
+ int rowsAffected = sqlite3_changes (_db);
147
+ NSString *message = [NSString stringWithFormat: @" %d row(s) affected" , rowsAffected];
148
+ result = [FLEXSQLResult message: message];
161
149
}
150
+ } else {
151
+ // An error occured executing the query
152
+ result = [FLEXSQLResult message: @(sqlite3_errmsg (_db) ?: " (Execution: empty error)" )];
162
153
}
154
+ } else {
155
+ // An error occurred creating the prepared statement
156
+ result = [FLEXSQLResult message: @(sqlite3_errmsg (_db) ?: " (Prepared statement: empty error)" )];
163
157
}
164
158
159
+ sqlite3_finalize (pstmt);
165
160
[self close ];
166
- return results ;
161
+ return result ;
167
162
}
168
163
164
+
165
+ #pragma mark - Private
166
+
169
167
- (id )objectForColumnIndex : (int )columnIdx stmt : (sqlite3_stmt*)stmt {
170
168
int columnType = sqlite3_column_type (stmt, columnIdx);
171
169
@@ -184,7 +182,7 @@ - (id)objectForColumnIndex:(int)columnIdx stmt:(sqlite3_stmt*)stmt {
184
182
return [self stringForColumnIndex: columnIdx stmt: stmt] ?: NSNull .null ;
185
183
}
186
184
}
187
-
185
+
188
186
- (NSString *)stringForColumnIndex : (int )columnIdx stmt : (sqlite3_stmt *)stmt {
189
187
if (sqlite3_column_type (stmt, columnIdx) == SQLITE_NULL || columnIdx < 0 ) {
190
188
return nil ;
0 commit comments