24
24
*/
25
25
package org .hibernate .internal .util ;
26
26
27
+ import java .io .Serializable ;
27
28
import java .util .ArrayList ;
28
29
import java .util .Arrays ;
29
30
import java .util .Iterator ;
@@ -66,6 +67,17 @@ public static String join(String seperator, String[] strings) {
66
67
return buf .toString ();
67
68
}
68
69
70
+ public static String joinWithQualifier (String [] values , String qualifier , String deliminator ) {
71
+ int length = values .length ;
72
+ if ( length == 0 ) return "" ;
73
+ StringBuilder buf = new StringBuilder ( length * values [0 ].length () )
74
+ .append ( qualify ( qualifier , values [0 ] ) );
75
+ for ( int i = 1 ; i < length ; i ++ ) {
76
+ buf .append ( deliminator ).append ( qualify ( qualifier , values [i ] ) );
77
+ }
78
+ return buf .toString ();
79
+ }
80
+
69
81
public static String join (String seperator , Iterator objects ) {
70
82
StringBuilder buf = new StringBuilder ();
71
83
if ( objects .hasNext () ) buf .append ( objects .next () );
@@ -89,6 +101,15 @@ public static String repeat(String string, int times) {
89
101
return buf .toString ();
90
102
}
91
103
104
+ public static String repeat (String string , int times , String deliminator ) {
105
+ StringBuilder buf = new StringBuilder ( ( string .length () * times ) + ( deliminator .length () * (times -1 ) ) )
106
+ .append ( string );
107
+ for ( int i = 1 ; i < times ; i ++ ) {
108
+ buf .append ( deliminator ).append ( string );
109
+ }
110
+ return buf .toString ();
111
+ }
112
+
92
113
public static String repeat (char character , int times ) {
93
114
char [] buffer = new char [times ];
94
115
Arrays .fill ( buffer , character );
@@ -661,4 +682,69 @@ public static String[] unquote(String[] names, Dialect dialect) {
661
682
}
662
683
return unquoted ;
663
684
}
685
+
686
+
687
+ public static final String BATCH_ID_PLACEHOLDER = "$$BATCH_ID_PLACEHOLDER$$" ;
688
+
689
+ public static StringBuilder buildBatchFetchRestrictionFragment (
690
+ String alias ,
691
+ String [] columnNames ,
692
+ Dialect dialect ) {
693
+ // the general idea here is to just insert a placeholder that we can easily find later...
694
+ if ( columnNames .length == 1 ) {
695
+ // non-composite key
696
+ return new StringBuilder ( StringHelper .qualify ( alias , columnNames [0 ] ) )
697
+ .append ( " in (" ).append ( BATCH_ID_PLACEHOLDER ).append ( ")" );
698
+ }
699
+ else {
700
+ // composite key - the form to use here depends on what the dialect supports.
701
+ if ( dialect .supportsRowValueConstructorSyntaxInInList () ) {
702
+ // use : (col1, col2) in ( (?,?), (?,?), ... )
703
+ StringBuilder builder = new StringBuilder ();
704
+ builder .append ( "(" );
705
+ boolean firstPass = true ;
706
+ String deliminator = "" ;
707
+ for ( String columnName : columnNames ) {
708
+ builder .append ( deliminator ).append ( StringHelper .qualify ( alias , columnName ) );
709
+ if ( firstPass ) {
710
+ firstPass = false ;
711
+ deliminator = "," ;
712
+ }
713
+ }
714
+ builder .append ( ") in (" );
715
+ builder .append ( BATCH_ID_PLACEHOLDER );
716
+ builder .append ( ")" );
717
+ return builder ;
718
+ }
719
+ else {
720
+ // use : ( (col1 = ? and col2 = ?) or (col1 = ? and col2 = ?) or ... )
721
+ // unfortunately most of this building needs to be held off until we know
722
+ // the exact number of ids :(
723
+ return new StringBuilder ( "(" ).append ( BATCH_ID_PLACEHOLDER ).append ( ")" );
724
+ }
725
+ }
726
+ }
727
+
728
+ public static String expandBatchIdPlaceholder (
729
+ String sql ,
730
+ Serializable [] ids ,
731
+ String alias ,
732
+ String [] keyColumnNames ,
733
+ Dialect dialect ) {
734
+ if ( keyColumnNames .length == 1 ) {
735
+ // non-composite
736
+ return StringHelper .replace ( sql , BATCH_ID_PLACEHOLDER , repeat ( "?" , ids .length , "," ) );
737
+ }
738
+ else {
739
+ // composite
740
+ if ( dialect .supportsRowValueConstructorSyntaxInInList () ) {
741
+ final String tuple = "(" + StringHelper .repeat ( "?" , keyColumnNames .length , "," );
742
+ return StringHelper .replace ( sql , BATCH_ID_PLACEHOLDER , repeat ( tuple , ids .length , "," ) );
743
+ }
744
+ else {
745
+ final String keyCheck = joinWithQualifier ( keyColumnNames , alias , " and " );
746
+ return replace ( sql , BATCH_ID_PLACEHOLDER , repeat ( keyCheck , ids .length , " or " ) );
747
+ }
748
+ }
749
+ }
664
750
}
0 commit comments