1717
1818import com .google .api .core .BetaApi ;
1919import com .google .api .core .InternalApi ;
20+ import com .google .bigtable .v2 .ArrayValue ;
2021import com .google .bigtable .v2 .ExecuteQueryRequest ;
2122import com .google .bigtable .v2 .Type ;
2223import com .google .bigtable .v2 .Value ;
2728import com .google .protobuf .ByteString ;
2829import com .google .protobuf .Timestamp ;
2930import java .util .HashMap ;
31+ import java .util .List ;
3032import java .util .Map ;
3133import javax .annotation .Nullable ;
3234import org .threeten .bp .Instant ;
@@ -65,6 +67,10 @@ public class Statement {
6567 Type .newBuilder ().setBytesType (Type .Bytes .getDefaultInstance ()).build ();
6668 private static final Type INT64_TYPE =
6769 Type .newBuilder ().setInt64Type (Type .Int64 .getDefaultInstance ()).build ();
70+ private static final Type FLOAT32_TYPE =
71+ Type .newBuilder ().setFloat32Type (Type .Float32 .getDefaultInstance ()).build ();
72+ private static final Type FLOAT64_TYPE =
73+ Type .newBuilder ().setFloat64Type (Type .Float64 .getDefaultInstance ()).build ();
6874 private static final Type BOOL_TYPE =
6975 Type .newBuilder ().setBoolType (Type .Bool .getDefaultInstance ()).build ();
7076 private static final Type TIMESTAMP_TYPE =
@@ -131,6 +137,24 @@ public Builder setLongParam(String paramName, @Nullable Long value) {
131137 return this ;
132138 }
133139
140+ /**
141+ * Sets a query parameter with the name {@code paramName} and the FLOAT32 typed value {@code
142+ * value}
143+ */
144+ public Builder setFloatParam (String paramName , @ Nullable Float value ) {
145+ params .put (paramName , float32ParamOf (value ));
146+ return this ;
147+ }
148+
149+ /**
150+ * Sets a query parameter with the name {@code paramName} and the FLOAT64 typed value {@code
151+ * value}
152+ */
153+ public Builder setDoubleParam (String paramName , @ Nullable Double value ) {
154+ params .put (paramName , float64ParamOf (value ));
155+ return this ;
156+ }
157+
134158 /**
135159 * Sets a query parameter with the name {@code paramName} and the BOOL typed value {@code value}
136160 */
@@ -156,6 +180,17 @@ public Builder setDateParam(String paramName, @Nullable Date value) {
156180 return this ;
157181 }
158182
183+ /**
184+ * Sets a query parameter with the name {@code paramName} and the ARRAY typed value {@code
185+ * value}. The array element type is specified by {@code arrayType} and the List elements must
186+ * be of the corresponding Java type. Null array elements are valid.
187+ */
188+ public <T > Builder setListParam (
189+ String paramName , @ Nullable List <T > value , SqlType .Array <T > arrayType ) {
190+ params .put (paramName , arrayParamOf (value , arrayType ));
191+ return this ;
192+ }
193+
159194 private static Value stringParamOf (@ Nullable String value ) {
160195 Value .Builder builder = nullValueWithType (STRING_TYPE );
161196 if (value != null ) {
@@ -180,6 +215,22 @@ private static Value int64ParamOf(@Nullable Long value) {
180215 return builder .build ();
181216 }
182217
218+ private static Value float32ParamOf (@ Nullable Float value ) {
219+ Value .Builder builder = nullValueWithType (FLOAT32_TYPE );
220+ if (value != null ) {
221+ builder .setFloatValue (value );
222+ }
223+ return builder .build ();
224+ }
225+
226+ private static Value float64ParamOf (@ Nullable Double value ) {
227+ Value .Builder builder = nullValueWithType (FLOAT64_TYPE );
228+ if (value != null ) {
229+ builder .setFloatValue (value );
230+ }
231+ return builder .build ();
232+ }
233+
183234 private static Value booleanParamOf (@ Nullable Boolean value ) {
184235 Value .Builder builder = nullValueWithType (BOOL_TYPE );
185236 if (value != null ) {
@@ -191,28 +242,120 @@ private static Value booleanParamOf(@Nullable Boolean value) {
191242 private static Value timestampParamOf (@ Nullable Instant value ) {
192243 Value .Builder builder = nullValueWithType (TIMESTAMP_TYPE );
193244 if (value != null ) {
194- builder .setTimestampValue (
195- Timestamp .newBuilder ()
196- .setSeconds (value .getEpochSecond ())
197- .setNanos (value .getNano ())
198- .build ());
245+ builder .setTimestampValue (toTimestamp (value ));
199246 }
200247 return builder .build ();
201248 }
202249
203250 private static Value dateParamOf (@ Nullable Date value ) {
204251 Value .Builder builder = nullValueWithType (DATE_TYPE );
205252 if (value != null ) {
206- builder .setDateValue (
207- com .google .type .Date .newBuilder ()
208- .setYear (value .getYear ())
209- .setMonth (value .getMonth ())
210- .setDay (value .getDayOfMonth ())
211- .build ());
253+ builder .setDateValue (toProtoDate (value ));
254+ }
255+ return builder .build ();
256+ }
257+
258+ private static <T > Value arrayParamOf (@ Nullable List <T > value , SqlType .Array <T > arrayType ) {
259+ Type type =
260+ Type .newBuilder ()
261+ .setArrayType (
262+ Type .Array .newBuilder ().setElementType (getElementType (arrayType )).build ())
263+ .build ();
264+ Value .Builder builder = nullValueWithType (type );
265+ if (value != null ) {
266+ builder .setArrayValue (arrayValueOf (value , arrayType ));
212267 }
213268 return builder .build ();
214269 }
215270
271+ private static Type getElementType (SqlType .Array <?> arrayType ) {
272+ switch (arrayType .getElementType ().getCode ()) {
273+ case BYTES :
274+ return BYTES_TYPE ;
275+ case STRING :
276+ return STRING_TYPE ;
277+ case INT64 :
278+ return INT64_TYPE ;
279+ case FLOAT32 :
280+ return FLOAT32_TYPE ;
281+ case FLOAT64 :
282+ return FLOAT64_TYPE ;
283+ case BOOL :
284+ return BOOL_TYPE ;
285+ case TIMESTAMP :
286+ return TIMESTAMP_TYPE ;
287+ case DATE :
288+ return DATE_TYPE ;
289+ default :
290+ throw new IllegalArgumentException (
291+ "Unsupported query parameter Array element type: " + arrayType .getElementType ());
292+ }
293+ }
294+
295+ private static ArrayValue arrayValueOf (List <?> value , SqlType .Array <?> arrayType ) {
296+ ArrayValue .Builder valueBuilder = ArrayValue .newBuilder ();
297+ for (Object element : value ) {
298+ if (element == null ) {
299+ valueBuilder .addValues (Value .getDefaultInstance ());
300+ continue ;
301+ }
302+ switch (arrayType .getElementType ().getCode ()) {
303+ case BYTES :
304+ ByteString bytesElem = (ByteString ) element ;
305+ valueBuilder .addValues (Value .newBuilder ().setBytesValue (bytesElem ).build ());
306+ break ;
307+ case STRING :
308+ String stringElem = (String ) element ;
309+ valueBuilder .addValues (Value .newBuilder ().setStringValue (stringElem ).build ());
310+ break ;
311+ case INT64 :
312+ Long longElem = (Long ) element ;
313+ valueBuilder .addValues (Value .newBuilder ().setIntValue (longElem ).build ());
314+ break ;
315+ case FLOAT32 :
316+ Float floatElem = (Float ) element ;
317+ valueBuilder .addValues (Value .newBuilder ().setFloatValue (floatElem ).build ());
318+ break ;
319+ case FLOAT64 :
320+ Double doubleElem = (Double ) element ;
321+ valueBuilder .addValues (Value .newBuilder ().setFloatValue (doubleElem ).build ());
322+ break ;
323+ case BOOL :
324+ Boolean boolElem = (Boolean ) element ;
325+ valueBuilder .addValues (Value .newBuilder ().setBoolValue (boolElem ).build ());
326+ break ;
327+ case TIMESTAMP :
328+ Instant timestampElem = (Instant ) element ;
329+ valueBuilder .addValues (
330+ Value .newBuilder ().setTimestampValue (toTimestamp (timestampElem )).build ());
331+ break ;
332+ case DATE :
333+ Date dateElem = (Date ) element ;
334+ valueBuilder .addValues (Value .newBuilder ().setDateValue (toProtoDate (dateElem )).build ());
335+ break ;
336+ default :
337+ throw new IllegalArgumentException (
338+ "Unsupported query parameter Array element type: " + arrayType .getElementType ());
339+ }
340+ }
341+ return valueBuilder .build ();
342+ }
343+
344+ private static Timestamp toTimestamp (Instant instant ) {
345+ return Timestamp .newBuilder ()
346+ .setSeconds (instant .getEpochSecond ())
347+ .setNanos (instant .getNano ())
348+ .build ();
349+ }
350+
351+ private static com .google .type .Date toProtoDate (Date date ) {
352+ return com .google .type .Date .newBuilder ()
353+ .setYear (date .getYear ())
354+ .setMonth (date .getMonth ())
355+ .setDay (date .getDayOfMonth ())
356+ .build ();
357+ }
358+
216359 private static Value .Builder nullValueWithType (Type type ) {
217360 return Value .newBuilder ().setType (type );
218361 }
0 commit comments