@@ -39,78 +39,95 @@ public void analyzeQCP4(){
3939 println ("Types of dynamic snippets: <types > " );
4040 println ("Counts for each type:\n <(n : size (d ) | n <- groupDynamicSnippetsByType (ds ), d := groupDynamicSnippetsByType (ds )[n ])> " );
4141 println ("Counts for each role:\n <(n : size (d ) | n <- groupDynamicSnippetsByRole (qcp4 ), d := groupDynamicSnippetsByRole (qcp4 )[n ])> " );
42+ for (q <- groupDynamicSnippetsByRole (qcp4 )["Other" ]) println (q .dynamicpart @at );
4243}
4344
44- private map [str , list [QuerySnippet ]] groupDynamicSnippetsByType (list [QuerySnippet ] ds ){
45+ public map [str , list [QuerySnippet ]] groupDynamicSnippetsByType (list [QuerySnippet ] ds ){
4546 res = ();
4647
4748 // group vars
48- res += ("var " : [d | d <- ds , dynamicsnippet (var (name (name (n )))) := d ]);
49+ res += ("Variable " : [d | d <- ds , dynamicsnippet (var (name (name (n )))) := d ]);
4950
5051 // group references to superglobals
51- res += ("superglobal " : [d | d <- ds , dynamicsnippet (fetchArrayDim (var (name (name (n ))), _)) := d , n in superglobals ]);
52+ res += ("Fetch Superglobal Element " : [d | d <- ds , dynamicsnippet (fetchArrayDim (var (name (name (n ))), _)) := d , n in superglobals ]);
5253
5354 // group fetchArrayDim
54- res += ("fetchArrayDim " : [d | d <- ds , dynamicsnippet (fetchArrayDim (var (name (name (n ))),_)) := d , n notin superglobals ]);
55+ res += ("Fetch Array Element " : [d | d <- ds , dynamicsnippet (fetchArrayDim (var (name (name (n ))),_)) := d , n notin superglobals ]);
5556 // needed case for 2-dimensional arrays
56- res ["fetchArrayDim " ] += [d | d <- ds , dynamicsnippet (fetchArrayDim (fetchArrayDim (var (name (name (n ))),_),_)) := d , n notin superglobals ];
57+ res ["Fetch Array Element " ] += [d | d <- ds , dynamicsnippet (fetchArrayDim (fetchArrayDim (var (name (name (n ))),_),_)) := d , n notin superglobals ];
5758
5859 // group function calls
59- res += ("call " : [d | d <- ds , dynamicsnippet (call (_,_)) := d ]);
60+ res += ("Function Call " : [d | d <- ds , dynamicsnippet (call (_,_)) := d ]);
6061
6162 // group ternary
62- res += ("ternary " : [d | d <- ds , dynamicsnippet (ternary (_,_,_)) := d ]);
63+ res += ("Ternary Operator " : [d | d <- ds , dynamicsnippet (ternary (_,_,_)) := d ]);
6364
64- if (size (ds ) != size (res ["var" ]) + size (res ["superglobal" ]) + size (res ["fetchArrayDim" ]) + size (res ["call" ]) + size (res ["ternary" ])){
65+ if (size (ds ) != size (res ["Variable" ]) + size (res ["Fetch Superglobal Element" ]) + size (res ["Fetch Array Element" ])
66+ + size (res ["Function Call" ]) + size (res ["Ternary Operator" ])){
67+
6568 println ("Warning: some dynamic snippets were not grouped. Type groupings may need additions." );
6669 }
6770 return res ;
6871}
6972
7073// groups all QCP4 occurrences based on what role their dynamic snippets take on
7174private map [str , list [QuerySnippet ]] groupDynamicSnippetsByRole (set [QueryString ] qs ){
72- res = ("param " : [], "name " : [], "other " : []);
75+ res = ("Parameter " : [], "Name " : [], "Other " : []);
7376 for (q <- qs ){
7477 indexes = getDynamicSnippetIndexes (q );
7578
7679 // returns true if this dynamic snippet is used as a parameter
7780 bool paramSnippet (int i ){
7881 // get previous static snippet
7982 if (staticsnippet (ss ) := q .snippets [i - 1 ]){
80- // perform regex matching on the static snippet to determine if the dynamic snippet is used as a parameter
81- if (/^.*WHERE\s [\w\.\` ]+\s?\=\s?[^\w\.\`]* $/i := ss ){
83+ // perform regex matching on the static snippet to determine if the dynamic snippet at i is used as a parameter
84+ if (/.* [\w\`\. ]+\s*\=|( \<\> )|(\!\=)| \< | \> |( \< \=)|( \> \=)\s*\'? \\ ? $/i := ss ){
8285 return true ;
8386 }
84- else if (/^.*AND\s[\w\.\`]+\s?\=\s?[^\w\.\`]* $/i := ss ){
87+ else if (/.*ORDER\sBY\s $/i := ss ){
8588 return true ;
8689 }
87- else if (/^.*OR\s[\w\.\`]+\s?\=\s?[^\w\.\`]* $/i := ss ){
90+ else if (/.*LIMIT\s $/i := ss ){
8891 return true ;
8992 }
90- else if (/^.*NOT\s[\w\.\`]+\s?\=\s?[^\w\.\`]*$/i := ss ){
93+ else {
94+ return false ;
95+ }
96+ }
97+ else {
98+ return false ;
99+ }
100+ }
101+
102+ // check for case of arithmetic in set clause
103+ bool setParamArithmetic (int i ){
104+ if (staticsnippet (ss ) := q .snippets [i - 1 ]){
105+ if (/.*<word :\w +> \s?\=\s?\(<word > \s?\+|\-\s?$/i := ss ){
91106 return true ;
92107 }
108+ else {
109+ return false ;
110+ }
111+ }
112+ else {
113+ return false ;
93114 }
94- return false ;
95115 }
96116
117+
97118 bool valuesParamSnippet (int index ){
98119 boundaries = <-1 ,-1 >;
99120 for (i <- [0 ..size (q .snippets )]){
100- if (staticsnippet (ss1 ) := q .snippets [i ] && /^.* VALUES\([^\)]* /i := ss1 ){
121+ if (staticsnippet (ss1 ) := q .snippets [i ] && /VALUES/i := ss1 ){
101122 boundaries [0 ] = i ;
102123 break ;
103124 }
104125 }
105126 if (boundaries [0 ] != -1 ){
106- for (i <- [boundaries [0 ]..size (q .snippets )]){
107- //find right paren
108- if (staticsnippet (ss2 ) := q .snippets [i ] && /\)$/i := ss2 ){
109- boundaries [1 ] = i ;
110- break ;
111- }
112- }
113- }
127+ // assume last snippet is the end of the VALUES clause
128+ boundaries [1 ] = size (q .snippets );
129+ }
130+
114131 if (boundaries [0 ] == -1 || boundaries [1 ] == -1 ){
115132 return false ;
116133 }
@@ -123,48 +140,50 @@ private map[str, list[QuerySnippet]] groupDynamicSnippetsByRole(set[QueryString]
123140 }
124141 }
125142
126- // returns true if this dynamic snippet is the parameter to a SET clause
127- bool setParamSnippet (int index ){
128- //finds the beginning of the SET clause of q, if it exists
129- setBegin = -1 ;
130- for (i <- [0 ..size (q .snippets )]){
131- if (staticsnippet (ss ) := q .snippets [i ] && /^.*SET\s[\w\.\`]+\s?\=\s?[^\w\.\`]*$/i := ss ){
132- setBegin = i ;
133- break ;
143+ bool nameSnippet (int i ){
144+ if (staticsnippet (ss ) := q .snippets [i - 1 ]){
145+ // perform regex matching on the static snippet to determine if the dynamic snippet is used as a parameter
146+ if (/^.*FROM\s$/ := ss ){
147+ return true ;
134148 }
135- }
136- if (setBegin != -1 ){
137- // check for the easy case of the dynamic snippet at index being the first assignment after the SET clause
138- if (index == setBegin + 1 && dynamicsnippet (_) := q .snippets [setBegin + 1 ]){
149+ else if (/^UPDATE\s$/ := ss ){
139150 return true ;
140151 }
141- // starting at the next snippet, look for <staticsnippet, dynamicsnippet> pairs of the form:
142- // atributename = $dynamicsnippet
143- else {
144- setBegin = setBegin + 2 ;
145- for (i <- [setBegin ..size (q .snippets ) - 1 ]){
146- if (index == i + 1 && staticsnippet (s ) := q .snippets [i ] && /^\'?\\ ?\s?\,\s?[\w\.\`]+\s?\=\s?\\ ?\'?$/ := s ){
147- return true ;
148- }
149- }
152+ else if (/^SELECT\s$/ := ss ){
153+ return true ;
154+ }
155+ else if (/^INSERT\sINTO\s$/ := ss ){
156+ return true ;
157+ }
158+ else if (/^.*DATABASE\s$/ := ss ){
159+ return true ;
160+ }
161+ else if (/^.*EXISTS\s$/ := ss ){
162+ return true ;
163+ }
164+ else if (/^.*USE\s$/ := ss ){
165+ return true ;
150166 }
151167 }
152168 return false ;
153169 }
154170
155171 for (i <- indexes , ds := q .snippets [i ]){
156- if (paramSnippet (i ) || setParamSnippet (i ) || valuesParamSnippet (i )){
157- res ["param" ] += ds ;
172+ if (paramSnippet (i ) || setParamArithmetic (i ) || valuesParamSnippet (i )){
173+ res ["Parameter" ] += ds ;
174+ }
175+ else if (nameSnippet (i )){
176+ res ["Name" ] += ds ;
158177 }
159178 else {
160- res ["other " ] += ds ;
179+ res ["Other " ] += ds ;
161180 }
162181 }
163182 }
164183 return res ;
165184}
166185// gets all dynamic query snippets from each querystring in qs
167- private list [QuerySnippet ] getDynamicSnippets (set [QueryString ] qs ) = [s | q <- qs , s <- q .snippets , dynamicsnippet (_) := s ];
186+ public list [QuerySnippet ] getDynamicSnippets (set [QueryString ] qs ) = [s | q <- qs , s <- q .snippets , dynamicsnippet (_) := s ];
168187
169188// gets the names of all the types used in dynamicsnippets
170189private set [str ] getQCP4DynamicSnippetTypes (list [QuerySnippet ] ds ) = {getName (e ) | d <- ds , dynamicsnippet (e ) := d };
0 commit comments