protected String asSql ( GString gstring , List < Object > values ) { String [ ] strings = gstring . getStrings ( ) ; if ( strings . length <= 0 ) { throw new IllegalArgumentException ( "No SQL specified in GString: " + gstring ) ; } boolean nulls = false ; StringBuilder buffer = new StringBuilder ( ) ; boolean warned = false ; Iterator < Object > iter = values . iterator ( ) ; for ( int i = 0 ; i < strings . length ; i ++ ) { String text = strings [ i ] ; if ( text != null ) { buffer . append ( text ) ; } if ( iter . hasNext ( ) ) { Object value = iter . next ( ) ; if ( value != null ) { if ( value instanceof ExpandedVariable ) { buffer . append ( ( ( ExpandedVariable ) value ) . getObject ( ) ) ; iter . remove ( ) ; } else { boolean validBinding = true ; if ( i < strings . length - 1 ) { String nextText = strings [ i + 1 ] ; if ( ( text . endsWith ( "\"" ) || text . endsWith ( "'" ) ) && ( nextText . startsWith ( "'" ) || nextText . startsWith ( "\"" ) ) ) { if ( ! warned ) { LOG . warning ( "In Groovy SQL please do not use quotes around dynamic expressions " + "(which start with $) as this means we cannot use a JDBC PreparedStatement " + "and so is a security hole. Groovy has worked around your mistake but the security hole is still there. " + "The expression so far is: " + buffer . toString ( ) + "?" + nextText ) ; warned = true ; } buffer . append ( value ) ; iter . remove ( ) ; validBinding = false ; } } if ( validBinding ) { buffer . append ( "?" ) ; } } } else { nulls = true ; iter . remove ( ) ; buffer . append ( "?'\"?" ) ; // will replace these with nullish values } } } String sql = buffer . toString ( ) ; if ( nulls ) { sql = nullify ( sql ) ; } return sql ; }
Hook to allow derived classes to override sql generation from GStrings .