@@ -41,6 +41,7 @@ private module Aiopg {
41
41
result = connection ( ) .getMember ( "cursor" ) .getReturn ( ) .getAwaited ( )
42
42
}
43
43
44
+ /** Calling `execute` on a `Cursor` constructs a query. */
44
45
class CursorExecuteCall extends SqlConstruction:: Range , DataFlow:: CallCfgNode {
45
46
CursorExecuteCall ( ) { this = cursor ( ) .getMember ( "execute" ) .getACall ( ) }
46
47
@@ -71,4 +72,49 @@ private module Aiopg {
71
72
72
73
override DataFlow:: Node getSql ( ) { result = sql }
73
74
}
75
+
76
+ /** An `Engine` is created when the result of calling `aiopg.sa.create_engine` is awaited. */
77
+ API:: Node engine ( ) {
78
+ result =
79
+ API:: moduleImport ( "aiopg" ) .getMember ( "sa" ) .getMember ( "create_engine" ) .getReturn ( ) .getAwaited ( )
80
+ }
81
+
82
+ /**
83
+ * A `SAConnection` is created when the result of calling `aquire` on an `Engine` is awaited.
84
+ */
85
+ API:: Node saConnection ( ) { result = engine ( ) .getMember ( "acquire" ) .getReturn ( ) .getAwaited ( ) }
86
+
87
+ /** Calling `execute` on a `SAConnection` constructs a query. */
88
+ class SAConnectionExecuteCall extends SqlConstruction:: Range , DataFlow:: CallCfgNode {
89
+ SAConnectionExecuteCall ( ) { this = saConnection ( ) .getMember ( "execute" ) .getACall ( ) }
90
+
91
+ override DataFlow:: Node getSql ( ) { result in [ this .getArg ( 0 ) , this .getArgByName ( "query" ) ] }
92
+ }
93
+
94
+ /**
95
+ * This is only needed to connect the argument to the execute call with the subsequnt awaiting.
96
+ * It should be obsolete once we have `API::CallNode` available.
97
+ */
98
+ private DataFlow:: TypeTrackingNode saConnectionExecuteCall (
99
+ DataFlow:: TypeTracker t , DataFlow:: Node sql
100
+ ) {
101
+ // saConnection created from engine
102
+ t .start ( ) and
103
+ sql = result .( SAConnectionExecuteCall ) .getSql ( )
104
+ or
105
+ exists ( DataFlow:: TypeTracker t2 | result = saConnectionExecuteCall ( t2 , sql ) .track ( t2 , t ) )
106
+ }
107
+
108
+ DataFlow:: Node saConnectionExecuteCall ( DataFlow:: Node sql ) {
109
+ saConnectionExecuteCall ( DataFlow:: TypeTracker:: end ( ) , sql ) .flowsTo ( result )
110
+ }
111
+
112
+ /** Awaiting the result of calling `execute` executes the query. */
113
+ class AwaitedSAConnectionExecuteCall extends SqlExecution:: Range {
114
+ DataFlow:: Node sql ;
115
+
116
+ AwaitedSAConnectionExecuteCall ( ) { this = awaited ( saConnectionExecuteCall ( sql ) ) }
117
+
118
+ override DataFlow:: Node getSql ( ) { result = sql }
119
+ }
74
120
}
0 commit comments