16
16
17
17
package com .google .cloud .spanner .connection ;
18
18
19
+ import com .google .api .gax .core .CredentialsProvider ;
20
+ import com .google .cloud .spanner .Dialect ;
19
21
import com .google .cloud .spanner .ErrorCode ;
20
22
import com .google .cloud .spanner .Options .RpcPriority ;
21
23
import com .google .cloud .spanner .SpannerException ;
31
33
import com .google .protobuf .util .Durations ;
32
34
import com .google .spanner .v1 .DirectedReadOptions ;
33
35
import com .google .spanner .v1 .RequestOptions .Priority ;
36
+ import java .lang .reflect .Constructor ;
37
+ import java .lang .reflect .InvocationTargetException ;
34
38
import java .util .Base64 ;
35
39
import java .util .EnumSet ;
36
40
import java .util .HashMap ;
@@ -172,8 +176,11 @@ public Integer convert(String value) {
172
176
}
173
177
}
174
178
175
- /** Converter from string to {@link Duration}. */
179
+ /** Converter from string to protobuf {@link Duration}. */
176
180
static class DurationConverter implements ClientSideStatementValueConverter <Duration > {
181
+ static final DurationConverter INSTANCE =
182
+ new DurationConverter ("('(\\ d{1,19})(s|ms|us|ns)'|(^\\ d{1,19})|NULL)" );
183
+
177
184
private final Pattern allowedValues ;
178
185
179
186
public DurationConverter (String allowedValues ) {
@@ -195,10 +202,15 @@ public Duration convert(String value) {
195
202
if (matcher .group (0 ).equalsIgnoreCase ("null" )) {
196
203
return Durations .fromNanos (0L );
197
204
} else {
198
- Duration duration =
199
- ReadOnlyStalenessUtil .createDuration (
200
- Long .parseLong (matcher .group (1 )),
201
- ReadOnlyStalenessUtil .parseTimeUnit (matcher .group (2 )));
205
+ Duration duration ;
206
+ if (matcher .group (3 ) != null ) {
207
+ duration = Durations .fromMillis (Long .parseLong (matcher .group (3 )));
208
+ } else {
209
+ duration =
210
+ ReadOnlyStalenessUtil .createDuration (
211
+ Long .parseLong (matcher .group (1 )),
212
+ ReadOnlyStalenessUtil .parseTimeUnit (matcher .group (2 )));
213
+ }
202
214
if (duration .getSeconds () == 0L && duration .getNanos () == 0 ) {
203
215
return null ;
204
216
}
@@ -254,6 +266,10 @@ public Duration convert(String value) {
254
266
/** Converter from string to possible values for read only staleness ({@link TimestampBound}). */
255
267
static class ReadOnlyStalenessConverter
256
268
implements ClientSideStatementValueConverter <TimestampBound > {
269
+ static final ReadOnlyStalenessConverter INSTANCE =
270
+ new ReadOnlyStalenessConverter (
271
+ "'((STRONG)|(MIN_READ_TIMESTAMP)[\\ t ]+((\\ d{4})-(\\ d{2})-(\\ d{2})([Tt](\\ d{2}):(\\ d{2}):(\\ d{2})(\\ .\\ d{1,9})?)([Zz]|([+-])(\\ d{2}):(\\ d{2})))|(READ_TIMESTAMP)[\\ t ]+((\\ d{4})-(\\ d{2})-(\\ d{2})([Tt](\\ d{2}):(\\ d{2}):(\\ d{2})(\\ .\\ d{1,9})?)([Zz]|([+-])(\\ d{2}):(\\ d{2})))|(MAX_STALENESS)[\\ t ]+((\\ d{1,19})(s|ms|us|ns))|(EXACT_STALENESS)[\\ t ]+((\\ d{1,19})(s|ms|us|ns)))'" );
272
+
257
273
private final Pattern allowedValues ;
258
274
private final CaseInsensitiveEnumMap <Mode > values = new CaseInsensitiveEnumMap <>(Mode .class );
259
275
@@ -539,7 +555,12 @@ public PgTransactionMode convert(String value) {
539
555
}
540
556
}
541
557
542
- /** Converter for converting strings to {@link RpcPriority} values. */
558
+ /**
559
+ * Converter for converting strings to {@link Priority} values.
560
+ *
561
+ * @deprecated Use {@link RpcPriorityEnumConverter} instead.
562
+ */
563
+ @ Deprecated
543
564
static class RpcPriorityConverter implements ClientSideStatementValueConverter <Priority > {
544
565
private final CaseInsensitiveEnumMap <Priority > values =
545
566
new CaseInsensitiveEnumMap <>(Priority .class );
@@ -569,12 +590,43 @@ public Priority convert(String value) {
569
590
}
570
591
}
571
592
593
+ /** Converter for converting strings to {@link RpcPriority} values. */
594
+ static class RpcPriorityEnumConverter implements ClientSideStatementValueConverter <RpcPriority > {
595
+ static final RpcPriorityEnumConverter INSTANCE = new RpcPriorityEnumConverter ();
596
+
597
+ private final CaseInsensitiveEnumMap <RpcPriority > values =
598
+ new CaseInsensitiveEnumMap <>(RpcPriority .class );
599
+
600
+ private RpcPriorityEnumConverter () {}
601
+
602
+ /** Constructor needed for reflection. */
603
+ public RpcPriorityEnumConverter (String allowedValues ) {}
604
+
605
+ @ Override
606
+ public Class <RpcPriority > getParameterClass () {
607
+ return RpcPriority .class ;
608
+ }
609
+
610
+ @ Override
611
+ public RpcPriority convert (String value ) {
612
+ if ("null" .equalsIgnoreCase (value )) {
613
+ return RpcPriority .UNSPECIFIED ;
614
+ }
615
+ return values .get (value );
616
+ }
617
+ }
618
+
572
619
/** Converter for converting strings to {@link SavepointSupport} values. */
573
620
static class SavepointSupportConverter
574
621
implements ClientSideStatementValueConverter <SavepointSupport > {
622
+ static final SavepointSupportConverter INSTANCE = new SavepointSupportConverter ();
623
+
575
624
private final CaseInsensitiveEnumMap <SavepointSupport > values =
576
625
new CaseInsensitiveEnumMap <>(SavepointSupport .class );
577
626
627
+ private SavepointSupportConverter () {}
628
+
629
+ /** Constructor needed for reflection. */
578
630
public SavepointSupportConverter (String allowedValues ) {}
579
631
580
632
@ Override
@@ -588,6 +640,30 @@ public SavepointSupport convert(String value) {
588
640
}
589
641
}
590
642
643
+ /** Converter for converting strings to {@link DdlInTransactionMode} values. */
644
+ static class DdlInTransactionModeConverter
645
+ implements ClientSideStatementValueConverter <DdlInTransactionMode > {
646
+ static final DdlInTransactionModeConverter INSTANCE = new DdlInTransactionModeConverter ();
647
+
648
+ private final CaseInsensitiveEnumMap <DdlInTransactionMode > values =
649
+ new CaseInsensitiveEnumMap <>(DdlInTransactionMode .class );
650
+
651
+ private DdlInTransactionModeConverter () {}
652
+
653
+ /** Constructor needed for reflection. */
654
+ public DdlInTransactionModeConverter (String allowedValues ) {}
655
+
656
+ @ Override
657
+ public Class <DdlInTransactionMode > getParameterClass () {
658
+ return DdlInTransactionMode .class ;
659
+ }
660
+
661
+ @ Override
662
+ public DdlInTransactionMode convert (String value ) {
663
+ return values .get (value );
664
+ }
665
+ }
666
+
591
667
static class ExplainCommandConverter implements ClientSideStatementValueConverter <String > {
592
668
@ Override
593
669
public Class <String > getParameterClass () {
@@ -648,4 +724,71 @@ public String convert(String filePath) {
648
724
return filePath ;
649
725
}
650
726
}
727
+
728
+ static class CredentialsProviderConverter
729
+ implements ClientSideStatementValueConverter <CredentialsProvider > {
730
+ static final CredentialsProviderConverter INSTANCE = new CredentialsProviderConverter ();
731
+
732
+ private CredentialsProviderConverter () {}
733
+
734
+ @ Override
735
+ public Class <CredentialsProvider > getParameterClass () {
736
+ return CredentialsProvider .class ;
737
+ }
738
+
739
+ @ Override
740
+ public CredentialsProvider convert (String credentialsProviderName ) {
741
+ if (!Strings .isNullOrEmpty (credentialsProviderName )) {
742
+ try {
743
+ Class <? extends CredentialsProvider > clazz =
744
+ (Class <? extends CredentialsProvider >) Class .forName (credentialsProviderName );
745
+ Constructor <? extends CredentialsProvider > constructor = clazz .getDeclaredConstructor ();
746
+ return constructor .newInstance ();
747
+ } catch (ClassNotFoundException classNotFoundException ) {
748
+ throw SpannerExceptionFactory .newSpannerException (
749
+ ErrorCode .INVALID_ARGUMENT ,
750
+ "Unknown or invalid CredentialsProvider class name: " + credentialsProviderName ,
751
+ classNotFoundException );
752
+ } catch (NoSuchMethodException noSuchMethodException ) {
753
+ throw SpannerExceptionFactory .newSpannerException (
754
+ ErrorCode .INVALID_ARGUMENT ,
755
+ "Credentials provider "
756
+ + credentialsProviderName
757
+ + " does not have a public no-arg constructor." ,
758
+ noSuchMethodException );
759
+ } catch (InvocationTargetException
760
+ | InstantiationException
761
+ | IllegalAccessException exception ) {
762
+ throw SpannerExceptionFactory .newSpannerException (
763
+ ErrorCode .INVALID_ARGUMENT ,
764
+ "Failed to create an instance of "
765
+ + credentialsProviderName
766
+ + ": "
767
+ + exception .getMessage (),
768
+ exception );
769
+ }
770
+ }
771
+ return null ;
772
+ }
773
+ }
774
+
775
+ /** Converter for converting strings to {@link Dialect} values. */
776
+ static class DialectConverter implements ClientSideStatementValueConverter <Dialect > {
777
+ static final DialectConverter INSTANCE = new DialectConverter ();
778
+
779
+ private final CaseInsensitiveEnumMap <Dialect > values =
780
+ new CaseInsensitiveEnumMap <>(Dialect .class );
781
+
782
+ private DialectConverter () {}
783
+
784
+ @ Override
785
+ public Class <Dialect > getParameterClass () {
786
+ return Dialect .class ;
787
+ }
788
+
789
+ @ Override
790
+ public Dialect convert (String value ) {
791
+ return values .get (value );
792
+ }
793
+ }
651
794
}
0 commit comments