@@ -894,58 +894,89 @@ public struct Delete : ExpressionType {
894
894
895
895
}
896
896
897
+ public struct RowCursor {
898
+ let statement : Statement
899
+ let columnNames : [ String : Int ]
900
+
901
+ public func next( ) throws -> Row ? {
902
+ return try statement. rowCursorNext ( ) . flatMap { Row ( columnNames, $0) }
903
+ }
904
+
905
+ public func map< T> ( _ transform: ( Row ) throws -> T ) throws -> [ T ] {
906
+ var elements = [ T] ( )
907
+ while true {
908
+ if let row = try next ( ) {
909
+ elements. append ( try transform ( row) )
910
+ } else {
911
+ break
912
+ }
913
+ }
914
+
915
+ return elements
916
+ }
917
+ }
918
+
897
919
extension Connection {
920
+
921
+ public func prepareCursor( _ query: QueryType ) throws -> RowCursor {
922
+ let expression = query. expression
923
+ let statement = try prepare ( expression. template, expression. bindings)
924
+ return RowCursor ( statement: statement, columnNames: try columnNamesForQuery ( query) )
925
+ }
898
926
899
927
public func prepare( _ query: QueryType ) throws -> AnySequence < Row > {
900
928
let expression = query. expression
901
929
let statement = try prepare ( expression. template, expression. bindings)
902
930
903
- let columnNames : [ String : Int ] = try {
904
- var ( columnNames, idx) = ( [ String: Int] ( ) , 0 )
905
- column: for each in query. clauses. select. columns {
906
- var names = each . expression. template. characters. split { $0 == " . " } . map ( String . init)
907
- let column = names. removeLast ( )
908
- let namespace = names. joined ( separator: " . " )
909
-
910
- func expandGlob( _ namespace: Bool ) -> ( ( QueryType ) throws -> Void ) {
911
- return { ( query: QueryType ) throws -> ( Void ) in
912
- var q = type ( of: query) . init ( query. clauses. from. name, database: query. clauses. from. database)
913
- q. clauses. select = query. clauses. select
914
- let e = q. expression
915
- var names = try self . prepare ( e. template, e. bindings) . columnNames. map { $0. quote ( ) }
916
- if namespace { names = names. map { " \( query. tableName ( ) . expression. template) . \( $0) " } }
917
- for name in names { columnNames [ name] = idx; idx += 1 }
918
- }
919
- }
931
+ let columnNames = try columnNamesForQuery ( query)
920
932
921
- if column == " * " {
922
- var select = query
923
- select. clauses. select = ( false , [ Expression < Void > ( literal: " * " ) as Expressible ] )
924
- let queries = [ select] + query. clauses. join. map { $0. query }
925
- if !namespace. isEmpty {
926
- for q in queries {
927
- if q. tableName ( ) . expression. template == namespace {
928
- try expandGlob ( true ) ( q)
929
- continue column
930
- }
933
+ return AnySequence {
934
+ AnyIterator { statement. next ( ) . map { Row ( columnNames, $0) } }
935
+ }
936
+ }
937
+
938
+ private func columnNamesForQuery( _ query: QueryType ) throws -> [ String : Int ] {
939
+ var ( columnNames, idx) = ( [ String: Int] ( ) , 0 )
940
+ column: for each in query. clauses. select. columns {
941
+ var names = each . expression. template. characters. split { $0 == " . " } . map ( String . init)
942
+ let column = names. removeLast ( )
943
+ let namespace = names. joined ( separator: " . " )
944
+
945
+ func expandGlob( _ namespace: Bool ) -> ( ( QueryType ) throws -> Void ) {
946
+ return { ( query: QueryType ) throws -> ( Void ) in
947
+ var q = type ( of: query) . init ( query. clauses. from. name, database: query. clauses. from. database)
948
+ q. clauses. select = query. clauses. select
949
+ let e = q. expression
950
+ var names = try self . prepare ( e. template, e. bindings) . columnNames. map { $0. quote ( ) }
951
+ if namespace { names = names. map { " \( query. tableName ( ) . expression. template) . \( $0) " } }
952
+ for name in names { columnNames [ name] = idx; idx += 1 }
953
+ }
954
+ }
955
+
956
+ if column == " * " {
957
+ var select = query
958
+ select. clauses. select = ( false , [ Expression < Void > ( literal: " * " ) as Expressible ] )
959
+ let queries = [ select] + query. clauses. join. map { $0. query }
960
+ if !namespace. isEmpty {
961
+ for q in queries {
962
+ if q. tableName ( ) . expression. template == namespace {
963
+ try expandGlob ( true ) ( q)
964
+ continue column
931
965
}
932
966
throw QueryError . noSuchTable ( name: namespace)
933
967
}
934
- for q in queries {
935
- try expandGlob ( query. clauses. join. count > 0 ) ( q)
936
- }
937
- continue
968
+ fatalError ( " no such table: \( namespace) " )
938
969
}
939
-
940
- columnNames [ each . expression. template] = idx
941
- idx += 1
970
+ for q in queries {
971
+ try expandGlob ( query. clauses. join. count > 0 ) ( q)
972
+ }
973
+ continue
942
974
}
943
- return columnNames
944
- } ( )
945
-
946
- return AnySequence {
947
- AnyIterator { statement. next ( ) . map { Row ( columnNames, $0) } }
975
+
976
+ columnNames [ each . expression. template] = idx
977
+ idx += 1
948
978
}
979
+ return columnNames
949
980
}
950
981
951
982
public func scalar< V : Value > ( _ query: ScalarQuery < V > ) throws -> V {
@@ -971,7 +1002,7 @@ extension Connection {
971
1002
}
972
1003
973
1004
public func pluck( _ query: QueryType ) throws -> Row ? {
974
- return try prepare ( query. limit ( 1 , query. clauses. limit? . offset) ) . makeIterator ( ) . next ( )
1005
+ return try prepareCursor ( query. limit ( 1 , query. clauses. limit? . offset) ) . next ( )
975
1006
}
976
1007
977
1008
/// Runs an `Insert` query.
0 commit comments