Skip to content

Commit 83f08f7

Browse files
committed
Add argument count to create(function:)
Allows for the definition of multiple functions with the same name but a differing number of arguments. Signed-off-by: Stephen Celis <stephen@stephencelis.com>
1 parent 6f3eef7 commit 83f08f7

File tree

4 files changed

+43
-39
lines changed

4 files changed

+43
-39
lines changed

SQLite/Database.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,10 @@ public final class Database {
387387
///
388388
/// :param: function The name of the function to create or redefine.
389389
///
390+
/// :param: argc The number of arguments that the function takes.
391+
/// If this parameter is -1, then the SQL function may
392+
/// take any number of arguments. (Default: -1.)
393+
///
390394
/// :param: deterministic Whether or not the function is deterministic. If
391395
/// the function always returns the same result for a
392396
/// given input, SQLite can make optimizations.
@@ -396,8 +400,8 @@ public final class Database {
396400
/// called. The block is called with an array of raw
397401
/// SQL values mapped to the function's parameters and
398402
/// should return a raw SQL value (or nil).
399-
public func create(#function: String, deterministic: Bool = false, _ block: [Binding?] -> Binding?) {
400-
try(SQLiteCreateFunction(handle, function, deterministic ? 1 : 0) { context, argc, argv in
403+
public func create(#function: String, argc: Int = -1, deterministic: Bool = false, _ block: [Binding?] -> Binding?) {
404+
try(SQLiteCreateFunction(handle, function, Int32(argc), deterministic ? 1 : 0) { context, argc, argv in
401405
let arguments: [Binding?] = map(0..<Int(argc)) { idx in
402406
let value = argv[Int(idx)]
403407
switch sqlite3_value_type(value) {

SQLite/Functions.swift

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -37,137 +37,137 @@ public extension Database {
3737
///
3838
/// :returns: A closure returning a SQL expression to call the function.
3939
public func create<Z: Value>(#function: String, deterministic: Bool = false, _ block: () -> Z) -> (() -> Expression<Z>) {
40-
return { self.create(function, deterministic) { _ in return block() }([]) }
40+
return { self.create(function, 0, deterministic) { _ in return block() }([]) }
4141
}
4242

4343
public func create<Z: Value>(#function: String, deterministic: Bool = false, _ block: () -> Z?) -> (() -> Expression<Z?>) {
44-
return { self.create(function, deterministic) { _ in return block() }([]) }
44+
return { self.create(function, 0, deterministic) { _ in return block() }([]) }
4545
}
4646

4747
// MARK: 1 Argument
4848

4949
public func create<Z: Value, A: Value>(#function: String, deterministic: Bool = false, _ block: A -> Z) -> (Expression<A> -> Expression<Z>) {
50-
return { self.create(function, deterministic) { block(asValue($0[0])) }([$0]) }
50+
return { self.create(function, 1, deterministic) { block(asValue($0[0])) }([$0]) }
5151
}
5252

5353
public func create<Z: Value, A: Value>(#function: String, deterministic: Bool = false, _ block: A? -> Z) -> (Expression<A?> -> Expression<Z>) {
54-
return { self.create(function, deterministic) { block($0[0].map(asValue)) }([$0]) }
54+
return { self.create(function, 1, deterministic) { block($0[0].map(asValue)) }([$0]) }
5555
}
5656

5757
public func create<Z: Value, A: Value>(#function: String, deterministic: Bool = false, _ block: A -> Z?) -> (Expression<A> -> Expression<Z?>) {
58-
return { self.create(function, deterministic) { block(asValue($0[0])) }([$0]) }
58+
return { self.create(function, 1, deterministic) { block(asValue($0[0])) }([$0]) }
5959
}
6060

6161
public func create<Z: Value, A: Value>(#function: String, deterministic: Bool = false, _ block: A? -> Z?) -> (Expression<A?> -> Expression<Z?>) {
62-
return { self.create(function, deterministic) { block($0[0].map(asValue)) }([$0]) }
62+
return { self.create(function, 1, deterministic) { block($0[0].map(asValue)) }([$0]) }
6363
}
6464

6565
// MARK: 2 Arguments
6666

6767
public func create<Z: Value, A: protocol<Value, Expressible>, B: Value>(#function: String, deterministic: Bool = false, _ block: (A, B) -> Z) -> ((A, Expression<B>) -> Expression<Z>) {
68-
return { self.create(function, deterministic) { block(asValue($0[0]), asValue($0[1])) }([$0, $1]) }
68+
return { self.create(function, 2, deterministic) { block(asValue($0[0]), asValue($0[1])) }([$0, $1]) }
6969
}
7070

7171
public func create<Z: Value, A: protocol<Value, Expressible>, B: Value>(#function: String, deterministic: Bool = false, _ block: (A?, B) -> Z) -> ((A?, Expression<B>) -> Expression<Z>) {
72-
return { self.create(function, deterministic) { block($0[0].map(asValue), asValue($0[1])) }([Expression<A?>(value: $0), $1]) }
72+
return { self.create(function, 2, deterministic) { block($0[0].map(asValue), asValue($0[1])) }([Expression<A?>(value: $0), $1]) }
7373
}
7474

7575
public func create<Z: Value, A: protocol<Value, Expressible>, B: Value>(#function: String, deterministic: Bool = false, _ block: (A, B?) -> Z) -> ((A, Expression<B?>) -> Expression<Z>) {
76-
return { self.create(function, deterministic) { block(asValue($0[0]), $0[1].map(asValue)) }([$0, $1]) }
76+
return { self.create(function, 2, deterministic) { block(asValue($0[0]), $0[1].map(asValue)) }([$0, $1]) }
7777
}
7878

7979
public func create<Z: Value, A: protocol<Value, Expressible>, B: Value>(#function: String, deterministic: Bool = false, _ block: (A?, B?) -> Z) -> ((A?, Expression<B?>) -> Expression<Z>) {
80-
return { self.create(function, deterministic) { block($0[0].map(asValue), $0[1].map(asValue)) }([Expression<A?>(value: $0), $1]) }
80+
return { self.create(function, 2, deterministic) { block($0[0].map(asValue), $0[1].map(asValue)) }([Expression<A?>(value: $0), $1]) }
8181
}
8282

8383
public func create<Z: Value, A: protocol<Value, Expressible>, B: Value>(#function: String, deterministic: Bool = false, _ block: (A, B) -> Z?) -> ((A, Expression<B>) -> Expression<Z?>) {
84-
return { self.create(function, deterministic) { block(asValue($0[0]), asValue($0[1])) }([$0, $1]) }
84+
return { self.create(function, 2, deterministic) { block(asValue($0[0]), asValue($0[1])) }([$0, $1]) }
8585
}
8686

8787
public func create<Z: Value, A: protocol<Value, Expressible>, B: Value>(#function: String, deterministic: Bool = false, _ block: (A?, B) -> Z?) -> ((A?, Expression<B>) -> Expression<Z?>) {
88-
return { self.create(function, deterministic) { block($0[0].map(asValue), asValue($0[1])) }([Expression<A?>(value: $0), $1]) }
88+
return { self.create(function, 2, deterministic) { block($0[0].map(asValue), asValue($0[1])) }([Expression<A?>(value: $0), $1]) }
8989
}
9090

9191
public func create<Z: Value, A: protocol<Value, Expressible>, B: Value>(#function: String, deterministic: Bool = false, _ block: (A, B?) -> Z?) -> ((A, Expression<B?>) -> Expression<Z?>) {
92-
return { self.create(function, deterministic) { block(asValue($0[0]), $0[1].map(asValue)) }([$0, $1]) }
92+
return { self.create(function, 2, deterministic) { block(asValue($0[0]), $0[1].map(asValue)) }([$0, $1]) }
9393
}
9494

9595
public func create<Z: Value, A: protocol<Value, Expressible>, B: Value>(#function: String, deterministic: Bool = false, _ block: (A?, B?) -> Z?) -> ((A?, Expression<B?>) -> Expression<Z?>) {
96-
return { self.create(function, deterministic) { block($0[0].map(asValue), $0[1].map(asValue)) }([Expression<A?>(value: $0), $1]) }
96+
return { self.create(function, 2, deterministic) { block($0[0].map(asValue), $0[1].map(asValue)) }([Expression<A?>(value: $0), $1]) }
9797
}
9898

9999
public func create<Z: Value, A: Value, B: Value>(#function: String, deterministic: Bool = false, _ block: (A, B) -> Z) -> ((Expression<A>, Expression<B>) -> Expression<Z>) {
100-
return { self.create(function, deterministic) { block(asValue($0[0]), asValue($0[1])) }([$0, $1]) }
100+
return { self.create(function, 2, deterministic) { block(asValue($0[0]), asValue($0[1])) }([$0, $1]) }
101101
}
102102

103103
public func create<Z: Value, A: Value, B: Value>(#function: String, deterministic: Bool = false, _ block: (A?, B) -> Z) -> ((Expression<A?>, Expression<B>) -> Expression<Z>) {
104-
return { self.create(function, deterministic) { block($0[0].map(asValue), asValue($0[1])) }([$0, $1]) }
104+
return { self.create(function, 2, deterministic) { block($0[0].map(asValue), asValue($0[1])) }([$0, $1]) }
105105
}
106106

107107
public func create<Z: Value, A: Value, B: Value>(#function: String, deterministic: Bool = false, _ block: (A, B?) -> Z) -> ((Expression<A>, Expression<B?>) -> Expression<Z>) {
108-
return { self.create(function, deterministic) { block(asValue($0[0]), $0[1].map(asValue)) }([$0, $1]) }
108+
return { self.create(function, 2, deterministic) { block(asValue($0[0]), $0[1].map(asValue)) }([$0, $1]) }
109109
}
110110

111111
public func create<Z: Value, A: Value, B: Value>(#function: String, deterministic: Bool = false, _ block: (A?, B?) -> Z) -> ((Expression<A?>, Expression<B?>) -> Expression<Z>) {
112-
return { self.create(function, deterministic) { block($0[0].map(asValue), $0[1].map(asValue)) }([$0, $1]) }
112+
return { self.create(function, 2, deterministic) { block($0[0].map(asValue), $0[1].map(asValue)) }([$0, $1]) }
113113
}
114114

115115
public func create<Z: Value, A: Value, B: Value>(#function: String, deterministic: Bool = false, _ block: (A, B) -> Z?) -> ((Expression<A>, Expression<B>) -> Expression<Z?>) {
116-
return { self.create(function, deterministic) { block(asValue($0[0]), asValue($0[1])) }([$0, $1]) }
116+
return { self.create(function, 2, deterministic) { block(asValue($0[0]), asValue($0[1])) }([$0, $1]) }
117117
}
118118

119119
public func create<Z: Value, A: Value, B: Value>(#function: String, deterministic: Bool = false, _ block: (A?, B) -> Z?) -> ((Expression<A?>, Expression<B>) -> Expression<Z?>) {
120-
return { self.create(function, deterministic) { block($0[0].map(asValue), asValue($0[1])) }([$0, $1]) }
120+
return { self.create(function, 2, deterministic) { block($0[0].map(asValue), asValue($0[1])) }([$0, $1]) }
121121
}
122122

123123
public func create<Z: Value, A: Value, B: Value>(#function: String, deterministic: Bool = false, _ block: (A, B?) -> Z?) -> ((Expression<A>, Expression<B?>) -> Expression<Z?>) {
124-
return { self.create(function, deterministic) { block(asValue($0[0]), $0[1].map(asValue)) }([$0, $1]) }
124+
return { self.create(function, 2, deterministic) { block(asValue($0[0]), $0[1].map(asValue)) }([$0, $1]) }
125125
}
126126

127127
public func create<Z: Value, A: Value, B: Value>(#function: String, deterministic: Bool = false, _ block: (A?, B?) -> Z?) -> ((Expression<A?>, Expression<B?>) -> Expression<Z?>) {
128-
return { self.create(function, deterministic) { block($0[0].map(asValue), $0[1].map(asValue)) }([$0, $1]) }
128+
return { self.create(function, 2, deterministic) { block($0[0].map(asValue), $0[1].map(asValue)) }([$0, $1]) }
129129
}
130130

131131
public func create<Z: Value, A: Value, B: protocol<Value, Expressible>>(#function: String, deterministic: Bool = false, _ block: (A, B) -> Z) -> ((Expression<A>, B) -> Expression<Z>) {
132-
return { self.create(function, deterministic) { block(asValue($0[0]), asValue($0[1])) }([$0, $1]) }
132+
return { self.create(function, 2, deterministic) { block(asValue($0[0]), asValue($0[1])) }([$0, $1]) }
133133
}
134134

135135
public func create<Z: Value, A: Value, B: protocol<Value, Expressible>>(#function: String, deterministic: Bool = false, _ block: (A?, B) -> Z) -> ((Expression<A?>, B) -> Expression<Z>) {
136-
return { self.create(function, deterministic) { block($0[0].map(asValue), asValue($0[1])) }([$0, $1]) }
136+
return { self.create(function, 2, deterministic) { block($0[0].map(asValue), asValue($0[1])) }([$0, $1]) }
137137
}
138138

139139
public func create<Z: Value, A: Value, B: protocol<Value, Expressible>>(#function: String, deterministic: Bool = false, _ block: (A, B?) -> Z) -> ((Expression<A>, B?) -> Expression<Z>) {
140-
return { self.create(function, deterministic) { block(asValue($0[0]), $0[1].map(asValue)) }([$0, Expression<B?>(value: $1)]) }
140+
return { self.create(function, 2, deterministic) { block(asValue($0[0]), $0[1].map(asValue)) }([$0, Expression<B?>(value: $1)]) }
141141
}
142142

143143
public func create<Z: Value, A: Value, B: protocol<Value, Expressible>>(#function: String, deterministic: Bool = false, _ block: (A?, B?) -> Z) -> ((Expression<A?>, B?) -> Expression<Z>) {
144-
return { self.create(function, deterministic) { block($0[0].map(asValue), $0[1].map(asValue)) }([$0, Expression<B?>(value: $1)]) }
144+
return { self.create(function, 2, deterministic) { block($0[0].map(asValue), $0[1].map(asValue)) }([$0, Expression<B?>(value: $1)]) }
145145
}
146146

147147
public func create<Z: Value, A: Value, B: protocol<Value, Expressible>>(#function: String, deterministic: Bool = false, _ block: (A, B) -> Z?) -> ((Expression<A>, B) -> Expression<Z?>) {
148-
return { self.create(function, deterministic) { block(asValue($0[0]), asValue($0[1])) }([$0, $1]) }
148+
return { self.create(function, 2, deterministic) { block(asValue($0[0]), asValue($0[1])) }([$0, $1]) }
149149
}
150150

151151
public func create<Z: Value, A: Value, B: protocol<Value, Expressible>>(#function: String, deterministic: Bool = false, _ block: (A?, B) -> Z?) -> ((Expression<A?>, B) -> Expression<Z?>) {
152-
return { self.create(function, deterministic) { block($0[0].map(asValue), asValue($0[1])) }([$0, $1]) }
152+
return { self.create(function, 2, deterministic) { block($0[0].map(asValue), asValue($0[1])) }([$0, $1]) }
153153
}
154154

155155
public func create<Z: Value, A: Value, B: protocol<Value, Expressible>>(#function: String, deterministic: Bool = false, _ block: (A, B?) -> Z?) -> ((Expression<A>, B?) -> Expression<Z?>) {
156-
return { self.create(function, deterministic) { block(asValue($0[0]), $0[1].map(asValue)) }([$0, Expression<B?>(value: $1)]) }
156+
return { self.create(function, 2, deterministic) { block(asValue($0[0]), $0[1].map(asValue)) }([$0, Expression<B?>(value: $1)]) }
157157
}
158158

159159
public func create<Z: Value, A: Value, B: protocol<Value, Expressible>>(#function: String, deterministic: Bool = false, _ block: (A?, B?) -> Z?) -> ((Expression<A?>, B?) -> Expression<Z?>) {
160-
return { self.create(function, deterministic) { block($0[0].map(asValue), $0[1].map(asValue)) }([$0, Expression<B?>(value: $1)]) }
160+
return { self.create(function, 2, deterministic) { block($0[0].map(asValue), $0[1].map(asValue)) }([$0, Expression<B?>(value: $1)]) }
161161
}
162162

163163
// MARK: -
164164

165-
private func create<Z: Value>(function: String, _ deterministic: Bool, _ block: [Binding?] -> Z) -> ([Expressible] -> Expression<Z>) {
166-
return { Expression<Z>(self.create(function, deterministic) { (arguments: [Binding?]) -> Z? in block(arguments) }($0)) }
165+
private func create<Z: Value>(function: String, _ argc: Int, _ deterministic: Bool, _ block: [Binding?] -> Z) -> ([Expressible] -> Expression<Z>) {
166+
return { Expression<Z>(self.create(function, argc, deterministic) { (arguments: [Binding?]) -> Z? in block(arguments) }($0)) }
167167
}
168168

169-
private func create<Z: Value>(function: String, _ deterministic: Bool, _ block: [Binding?] -> Z?) -> ([Expressible] -> Expression<Z?>) {
170-
create(function: function, deterministic: deterministic) { block($0)?.datatypeValue }
169+
private func create<Z: Value>(function: String, _ argc: Int, _ deterministic: Bool, _ block: [Binding?] -> Z?) -> ([Expressible] -> Expression<Z?>) {
170+
create(function: function, argc: argc, deterministic: deterministic) { block($0)?.datatypeValue }
171171
return { arguments in wrap(quote(identifier: function), Expression<Z>.join(", ", arguments)) }
172172
}
173173

SQLite/SQLite-Bridging.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,15 @@ void _SQLiteCreateFunction(sqlite3_context * context, int argc, sqlite3_value **
5454
((SQLiteCreateFunctionCallback)sqlite3_user_data(context))(context, argc, argv);
5555
}
5656

57-
int SQLiteCreateFunction(sqlite3 * handle, const char * name, int deterministic, SQLiteCreateFunctionCallback callback) {
57+
int SQLiteCreateFunction(sqlite3 * handle, const char * name, int argc, int deterministic, SQLiteCreateFunctionCallback callback) {
5858
if (callback) {
5959
int flags = SQLITE_UTF8;
6060
if (deterministic) {
6161
#ifdef SQLITE_DETERMINISTIC
6262
flags |= SQLITE_DETERMINISTIC;
6363
#endif
6464
}
65-
return sqlite3_create_function_v2(handle, name, -1, flags, Block_copy(callback), &_SQLiteCreateFunction, 0, 0, 0); // FIXME: leak
65+
return sqlite3_create_function_v2(handle, name, argc, flags, Block_copy(callback), &_SQLiteCreateFunction, 0, 0, 0); // FIXME: leak
6666
} else {
6767
return sqlite3_create_function_v2(handle, name, 0, 0, 0, 0, 0, 0, 0);
6868
}

SQLite/SQLite-Bridging.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ typedef void (^SQLiteTraceCallback)(const char * SQL);
3131
void SQLiteTrace(sqlite3 * handle, SQLiteTraceCallback callback);
3232

3333
typedef void (^SQLiteCreateFunctionCallback)(sqlite3_context * context, int argc, sqlite3_value ** argv);
34-
int SQLiteCreateFunction(sqlite3 * handle, const char * name, int deterministic, SQLiteCreateFunctionCallback callback);
34+
int SQLiteCreateFunction(sqlite3 * handle, const char * name, int argc, int deterministic, SQLiteCreateFunctionCallback callback);
3535

3636
typedef int (^SQLiteCreateCollationCallback)(const char * lhs, const char * rhs);
3737
int SQLiteCreateCollation(sqlite3 * handle, const char * name, SQLiteCreateCollationCallback callback);

0 commit comments

Comments
 (0)