-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathSQLiteImpl.iOS.uno
119 lines (101 loc) · 4.41 KB
/
SQLiteImpl.iOS.uno
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
using Fuse;
using Fuse.Scripting;
using Fuse.Reactive;
using ObjC;
using Uno;
using Uno.Collections;
using Uno.Compiler.ExportTargetInterop;
using Bolav.ForeignHelpers;
// http://www.appcoda.com/sqlite-database-ios-app-tutorial/
[Require("Source.Include", "@{ForeignDict:Include}")]
[TargetSpecificImplementation]
public extern(iOS) static class SQLiteImpl {
// TODO: Rewrite to an exception thrower, to make this modular
public static void ThrowException (string exception) {
throw new Fuse.Scripting.Error(exception);
}
[Require("Source.Include", "sqlite3.h")]
[Require("LinkLibrary", "sqlite3")]
[Foreign(Language.ObjC)]
public static extern IntPtr OpenImpl(string filename)
@{
sqlite3 *sqlite3Database;
BOOL openDatabaseResult = sqlite3_open([filename UTF8String], &sqlite3Database);
return sqlite3Database;
@}
[Foreign(Language.ObjC)]
public static extern void ExecImpl(IntPtr db, string statement, string[] param)
@{
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare_v2((sqlite3 *)db, [statement UTF8String], -1, &compiledStatement, NULL) != SQLITE_OK) {
NSLog(@"Prepare failure: %s", sqlite3_errmsg((sqlite3 *)db));
@{ThrowException(string):Call([NSString stringWithUTF8String:sqlite3_errmsg((sqlite3 *)db)])};
}
for (int i=0; i<param.count; i++) {
if (sqlite3_bind_text(compiledStatement, i + 1, [param[i] UTF8String], -1, NULL) != SQLITE_OK) {
NSLog(@"Bind %d failure: %s", i, sqlite3_errmsg((sqlite3 *)db));
@{ThrowException(string):Call([NSString stringWithUTF8String:sqlite3_errmsg((sqlite3 *)db)])};
}
}
if (sqlite3_step(compiledStatement) != SQLITE_DONE) {
NSLog(@"Step failure: %s", sqlite3_errmsg((sqlite3 *)db));
@{ThrowException(string):Call([NSString stringWithUTF8String:sqlite3_errmsg((sqlite3 *)db)])};
}
sqlite3_finalize(compiledStatement);
return;
@}
[Foreign(Language.ObjC)]
public static extern void CloseImpl(IntPtr db)
@{
sqlite3_close((sqlite3 *)db);
return;
@}
[Foreign(Language.ObjC)]
public static extern void QueryImpl(ForeignList result, IntPtr db, string statement, string[] param)
@{
sqlite3_stmt *compiledStatement;
NSMutableArray *columnNames = [[NSMutableArray alloc] init];
// Load all data from database to memory.
BOOL prepareStatementResult = sqlite3_prepare_v2((sqlite3 *)db, [statement UTF8String], -1, &compiledStatement, NULL);
if(prepareStatementResult != SQLITE_OK) {
NSLog(@"Prepare failure: %s", sqlite3_errmsg((sqlite3 *)db));
@{ThrowException(string):Call([NSString stringWithUTF8String:sqlite3_errmsg((sqlite3 *)db)])};
}
for (int i=0; i<param.count; i++) {
if (sqlite3_bind_text(compiledStatement, i + 1, [param[i] UTF8String], -1, NULL) != SQLITE_OK) {
NSLog(@"Bind %d failure: %s", i, sqlite3_errmsg((sqlite3 *)db));
@{ThrowException(string):Call([NSString stringWithUTF8String:sqlite3_errmsg((sqlite3 *)db)])};
}
}
int sqlite_ret;
while((sqlite_ret = sqlite3_step(compiledStatement)) == SQLITE_ROW) {
// Initialize the mutable array that will contain the data of a fetched row.
id<UnoObject> row = @{ForeignList:Of(result).NewDictRow():Call()};
// Get the total number of columns.
int totalColumns = sqlite3_column_count(compiledStatement);
// Go through all columns and fetch each column data.
for (int i=0; i<totalColumns; i++){
// Convert the column data to text (characters).
char *dbDataAsChars;
// Keep the current column name.
if (columnNames.count != totalColumns) {
dbDataAsChars = (char *)sqlite3_column_name(compiledStatement, i);
[columnNames addObject:[NSString stringWithUTF8String:dbDataAsChars]];
}
dbDataAsChars = (char *)sqlite3_column_text(compiledStatement, i);
// If there are contents in the currenct column (field) then add them to the current row array.
if (dbDataAsChars != NULL) {
// Convert the characters to string.
@{ForeignDict:Of(row).SetKeyVal(string,string):Call([columnNames objectAtIndex:i], [NSString stringWithUTF8String:dbDataAsChars])};
}
else {
@{ForeignDict:Of(row).SetKeyVal(string,string):Call([columnNames objectAtIndex:i], nil)};
}
}
}
if (sqlite_ret != SQLITE_DONE) {
NSLog(@"sqlite_ret: %d", sqlite_ret);
@{ThrowException(string):Call([NSString stringWithUTF8String:sqlite3_errmsg((sqlite3 *)db)])};
}
@}
}