Better Get a Bucket
We reenter getBucketResults() at the lines below:
1 if ( user_interests_exist || 2 user_certifications_exist || 3 user_job_titles_exist ) 4 { 5 // 6 // we know the user and they have a profile 7 // 8 9 if ( user_interests_exist && 10 user_certifications_exist && 11 user_job_titles_exist ) 12 { 13 setBucketResults( 1 ); 14 } 15 else 16 { 17 if ( user_interests_exist ^ 18 user_certifications_exist ^ 19 user_job_titles_exist ) 20 { 21 setBucketResults( 1 ); 22 } 23 else 24 { 25 setBucketResults( 0 ); 26 } 27 } 28 }
Right away we see whether any of our flags are set. Using the || (or) comparison operator, we first see if even one of the flags is true. If so, we know that a profile of some kind exists. We then get optimistic, on lines 914, and check to see if all of the flags are true. Wow! You filled out the entire customization profile! Good for you! Collect $200 Monopoly dollars and call setBucketResults( 1 ). We'll see that in a bit. If they aren't all true, we move to lines 1726, and use the ^ (exclusive or) operator. The if statement evaluates to true if just one of the three flags is true, and calls setBucketResults( 1 ). If two of the flags are true, it calls setBucketResults( 0 ).
Are you ready for setBucketResults()? Let's check it out! Pay careful attention because we conjure the feared recursion demon.
29 private boolean setBucketResults ( int level ) 30 { 31 Recordset RS = null; 32 Recordset Count = null; 33 34 switch ( level ) 35 { 36 case 0 : 37 try 38 { 39 buildQueryLevel_0(); 40 RS = executeQueryString(); 41 } 42 catch ( IllegalArgumentException e ) 43 { 44 RS = null; 45 } 46 break; 47 48 case 1 : 49 try 50 { 51 local_sql_query_string = null; 52 buildQueryLevel_1(); 53 RS = executeQueryString 54 ( local_sql_query_string.toString() ); 55 } 56 catch ( IllegalArgumentException e ) 57 { 58 RS = null; 59 } 60 break; 61 62 default : 63 return ( false ); 64 }
First things first, we perform a switch-case on the level that was passed in. Staying true to our running example, let's say that the user_job_titles_exist and user_certifications_exist flags were set to true by verifyClauses(). As a result, we called setBucketResults( 0 ). Level 0 is handled by lines 3647. Within another tidy form, the try-catch, our intrepid developer calls buildQueryLevel_0, and then sets his Recordset object (initialized on Line 31) equal to the function executeQueryString(). To avoid the risk of experiencing too much recursion ourselves, let's get to those functions a little bit later. Continuing...
65 if ( RS != null ) 66 { 67 if ( RS.getRecordCount() >= 68 MINIMUM_REQUIRED_RESULT_SIZE ) 69 { 70 setRecordset( RS ); 71 switch (level) 72 { 73 case 0: 74 setResultCount( Math.min 75 ( this.getPreferredResultCount(), 76 RS.getRecordCount() ) ); 77 78 setTotalAvailableCount( RS.getRecordCount() ); 79 break; 80 81 case 1: 82 setResultCount( Math.min 83 ( this.getPreferredResultCount(), 84 RS.getRecordCount() ) ); 85 86 setTotalAvailableCount( RS.getRecordCount() ); 87 break; 88 89 default: 90 setTotalAvailableCount( 0 ); 91 break; 92 } 93 return ( true ); 94 95 } 96 else 97 { 98 RS = null; 99 return ( setBucketResults ( ++level ) ); 100 } 101 } 102 else 103 { 104 return ( setBucketResults ( ++level ) ); 105 } 106 107 }
On Line 65, we check for the Recordset, RS, returned from executeQueryString(). If RS contains data, we see whether the RecordCount is greater than the minimum number of results to return to the ASP (the minimum is set to 1, incidentally). If there is more than one row in the Recordset, we step into another switch construct. We set the ResultCount equal to the lesser of the preferred result count or the total number of rows. For books, the preferred result count is 5. The total number of records available is also stored in the TotalAvailableCount.
If the Recordset has fewer than the minimum number of rows or is null, we recurse and call setBucketResults again. This time, the level has been incremented by 1. In our case, because the level was 0, we call setBucketResults( 1 ). This executes the code on lines 4860:
local_sql_query_string = null; buildQueryLevel_1(); RS = executeQueryString ( local_sql_query_string.toString() );