55
55
/**
56
56
* @author jmussler
57
57
*/
58
+ @ Immutable
58
59
class StoredProcedure {
59
60
60
61
private static final int TRUNCATE_DEBUG_PARAMS_MAX_LENGTH = 1024 ;
61
62
private static final String TRUNCATE_DEBUG_PARAMS_ELLIPSIS = " ..." ;
62
63
63
64
private static final Logger LOG = LoggerFactory .getLogger (StoredProcedure .class );
64
65
65
- private final List <StoredProcedureParameter > params = new ArrayList <StoredProcedureParameter >();
66
-
67
66
private final String name ;
68
- private String query = null ;
69
- private Class <?> returnType = null ;
67
+ private final List <StoredProcedureParameter > params ;
68
+ private final int [] types ;
69
+
70
+ private final String sqlParameterList ;
71
+ private final String query ;
72
+
73
+ private final Class <?> returnType ;
70
74
71
75
// whether the result type is a collection (List)
72
- private boolean collectionResult = false ;
76
+ private final boolean collectionResult ;
73
77
private final boolean runOnAllShards ;
74
78
private final boolean searchShards ;
75
- private boolean autoPartition ;
79
+ private final boolean autoPartition ;
76
80
private final boolean parallel ;
77
81
private final boolean readOnly ;
78
82
private final WriteTransaction writeTransaction ;
79
83
80
- private Executor executor = null ;
84
+ private final Executor executor ;
81
85
82
- private VirtualShardKeyStrategy shardStrategy ;
83
- private List <ShardKeyParameter > shardKeyParameters = null ;
84
- private final RowMapper <?> resultMapper ;
85
-
86
- private int [] types = null ;
86
+ private final VirtualShardKeyStrategy shardStrategy ;
87
+ private final List <ShardKeyParameter > shardKeyParameters ;
87
88
88
89
private static final Executor MULTI_ROW_SIMPLE_TYPE_EXECUTOR = new MultiRowSimpleTypeExecutor ();
89
90
private static final Executor MULTI_ROW_TYPE_MAPPER_EXECUTOR = new MultiRowTypeMapperExecutor ();
@@ -93,26 +94,34 @@ class StoredProcedure {
93
94
private final long timeout ;
94
95
private final AdvisoryLock adivsoryLock ;
95
96
96
- public StoredProcedure (final String name , final java .lang .reflect .Type genericType ,
97
- final VirtualShardKeyStrategy sStrategy , final boolean runOnAllShards , final boolean searchShards ,
97
+ public StoredProcedure (final String name , final String query , final List < StoredProcedureParameter > params , final java .lang .reflect .Type genericType ,
98
+ final VirtualShardKeyStrategy sStrategy , final List < ShardKeyParameter > shardKeyParameters , final boolean runOnAllShards , final boolean searchShards ,
98
99
final boolean parallel , final RowMapper <?> resultMapper , final long timeout ,
99
100
final AdvisoryLock advisoryLock , final boolean useValidation , final boolean readOnly ,
100
101
final WriteTransaction writeTransaction ) throws InstantiationException , IllegalAccessException {
101
102
this .name = name ;
103
+ this .params = new ArrayList <>(params );
104
+ this .types = createTypes (params );
105
+
106
+ this .sqlParameterList = createSqlParameterList (params );
107
+ this .query = (query != null ? query : defaultQuery (name , sqlParameterList ));
108
+
102
109
this .runOnAllShards = runOnAllShards ;
103
110
this .searchShards = searchShards ;
104
111
this .parallel = parallel ;
105
112
this .readOnly = readOnly ;
106
- this .resultMapper = resultMapper ;
107
113
this .writeTransaction = writeTransaction ;
108
114
109
115
this .adivsoryLock = advisoryLock ;
110
116
this .timeout = timeout ;
111
117
112
- shardStrategy = sStrategy ;
118
+ this .shardStrategy = sStrategy ;
119
+ this .shardKeyParameters = new ArrayList <>(shardKeyParameters );
113
120
114
- ValueTransformer <?, ?> valueTransformerForClass = null ;
121
+ this . autoPartition = isAutoPartition ( shardKeyParameters ) ;
115
122
123
+ ValueTransformer <?, ?> valueTransformerForClass = null ;
124
+ Executor exec ;
116
125
if (genericType instanceof ParameterizedType ) {
117
126
final ParameterizedType pType = (ParameterizedType ) genericType ;
118
127
@@ -125,70 +134,53 @@ public StoredProcedure(final String name, final java.lang.reflect.Type genericTy
125
134
126
135
if (valueTransformerForClass != null
127
136
|| SingleRowSimpleTypeExecutor .SIMPLE_TYPES .containsKey (returnType )) {
128
- executor = MULTI_ROW_SIMPLE_TYPE_EXECUTOR ;
137
+ exec = MULTI_ROW_SIMPLE_TYPE_EXECUTOR ;
129
138
} else {
130
- executor = MULTI_ROW_TYPE_MAPPER_EXECUTOR ;
139
+ exec = MULTI_ROW_TYPE_MAPPER_EXECUTOR ;
131
140
}
132
141
133
142
collectionResult = true ;
134
143
} else {
135
- executor = SINGLE_ROW_TYPE_MAPPER_EXECUTOR ;
144
+ collectionResult = false ;
145
+ exec = SINGLE_ROW_TYPE_MAPPER_EXECUTOR ;
136
146
returnType = (Class <?>) pType .getRawType ();
137
147
}
138
148
139
149
} else {
150
+ collectionResult = false ;
140
151
returnType = (Class <?>) genericType ;
141
152
142
153
// check if we have a value transformer (and initialize the registry):
143
154
valueTransformerForClass = GlobalValueTransformerLoader .getValueTransformerForClass (returnType );
144
155
145
156
if (valueTransformerForClass != null || SingleRowSimpleTypeExecutor .SIMPLE_TYPES .containsKey (returnType )) {
146
- executor = SINGLE_ROW_SIMPLE_TYPE_EXECUTOR ;
157
+ exec = SINGLE_ROW_SIMPLE_TYPE_EXECUTOR ;
147
158
} else {
148
159
if (resultMapper != null ) {
149
- executor = new SingleRowCustomMapperExecutor (resultMapper );
160
+ exec = new SingleRowCustomMapperExecutor (resultMapper );
150
161
} else {
151
- executor = SINGLE_ROW_TYPE_MAPPER_EXECUTOR ;
162
+ exec = SINGLE_ROW_TYPE_MAPPER_EXECUTOR ;
152
163
}
153
164
}
154
165
}
155
166
156
167
if (this .timeout > 0 || (this .adivsoryLock != null && !(this .adivsoryLock .equals (AdvisoryLock .NoLock .LOCK )))) {
157
168
158
169
// Wrapper provides locking and changing of session settings functionality
159
- this . executor = new ExecutorWrapper (executor , this .timeout , this .adivsoryLock );
170
+ exec = new ExecutorWrapper (exec , this .timeout , this .adivsoryLock );
160
171
}
161
172
162
173
if (useValidation ) {
163
- this . executor = new ValidationExecutorWrapper (this . executor );
174
+ exec = new ValidationExecutorWrapper (exec );
164
175
}
165
176
166
177
if (valueTransformerForClass != null ) {
167
178
168
179
// we need to transform the return value by the global value transformer.
169
180
// add the transformation to the as a transformerExecutor
170
- this . executor = new GlobalTransformerExecutorWrapper (this . executor );
181
+ exec = new GlobalTransformerExecutorWrapper (exec );
171
182
}
172
- }
173
-
174
- public void addParam (final StoredProcedureParameter p ) {
175
- params .add (p );
176
- }
177
-
178
- public void setVirtualShardKeyStrategy (final VirtualShardKeyStrategy s ) {
179
- shardStrategy = s ;
180
- }
181
-
182
- public void addShardKeyParameter (final int jp , final Class <?> clazz ) {
183
- if (shardKeyParameters == null ) {
184
- shardKeyParameters = new ArrayList <ShardKeyParameter >(1 );
185
- }
186
-
187
- if (List .class .isAssignableFrom (clazz )) {
188
- autoPartition = true ;
189
- }
190
-
191
- shardKeyParameters .add (new ShardKeyParameter (jp ));
183
+ this .executor = exec ;
192
184
}
193
185
194
186
public String getName () {
@@ -217,15 +209,15 @@ public Object[] getParams(final Object[] origParams, final Connection connection
217
209
}
218
210
219
211
public int [] getTypes () {
220
- if ( types == null ) {
221
- types = new int [ params . size ()];
212
+ return types ;
213
+ }
222
214
223
- int i = 0 ;
224
- for (final StoredProcedureParameter p : params ) {
225
- types [i ++] = p .getType ();
226
- }
215
+ private static int [] createTypes (final List <StoredProcedureParameter > params ) {
216
+ int [] types = new int [params .size ()];
217
+ int i = 0 ;
218
+ for (final StoredProcedureParameter p : params ) {
219
+ types [i ++] = p .getType ();
227
220
}
228
-
229
221
return types ;
230
222
}
231
223
@@ -238,7 +230,7 @@ public int getShardId(final Object[] objs) {
238
230
int i = 0 ;
239
231
Object obj ;
240
232
for (final ShardKeyParameter p : shardKeyParameters ) {
241
- obj = objs [p .javaPos ];
233
+ obj = objs [p .getPos () ];
242
234
if (obj instanceof ShardedObject ) {
243
235
obj = ((ShardedObject ) obj ).getShardKey ();
244
236
}
@@ -251,6 +243,10 @@ public int getShardId(final Object[] objs) {
251
243
}
252
244
253
245
public String getSqlParameterList () {
246
+ return sqlParameterList ;
247
+ }
248
+
249
+ private static String createSqlParameterList (final List <StoredProcedureParameter > params ) {
254
250
String s = "" ;
255
251
boolean first = true ;
256
252
for (int i = 1 ; i <= params .size (); ++i ) {
@@ -266,18 +262,14 @@ public String getSqlParameterList() {
266
262
return s ;
267
263
}
268
264
269
- public void setQuery (final String sql ) {
270
- query = sql ;
271
- }
272
-
273
265
public String getQuery () {
274
- if (query == null ) {
275
- query = "SELECT * FROM " + name + " ( " + getSqlParameterList () + " )" ;
276
- }
277
-
278
266
return query ;
279
267
}
280
268
269
+ private static String defaultQuery (final String name , final String sqlParameterList ) {
270
+ return "SELECT * FROM " + name + " ( " + sqlParameterList + " )" ;
271
+ }
272
+
281
273
/**
282
274
* build execution string like create_or_update_multiple_objects({"(a,b)","(c,d)" }).
283
275
*
@@ -384,6 +376,15 @@ private Map<Integer, Object[]> partitionArguments(final DataSourceProvider dataS
384
376
return argumentsByShardId ;
385
377
}
386
378
379
+ private boolean isAutoPartition (final List <ShardKeyParameter > shardKeyParameters ) {
380
+ for (ShardKeyParameter p : shardKeyParameters ) {
381
+ if (List .class .isAssignableFrom (p .getType ())) {
382
+ return true ;
383
+ }
384
+ }
385
+ return false ;
386
+ }
387
+
387
388
@ Immutable
388
389
private static final class Call implements Callable <Object > {
389
390
0 commit comments