20
20
import io .airbyte .db .DataTypeUtils ;
21
21
import io .airbyte .db .SourceOperations ;
22
22
import io .airbyte .db .jdbc .AbstractJdbcCompatibleSourceOperations ;
23
+ import io .airbyte .db .jdbc .DateTimeConverter ;
23
24
import io .airbyte .protocol .models .JsonSchemaType ;
24
25
import java .sql .PreparedStatement ;
25
26
import java .sql .ResultSet ;
26
27
import java .sql .SQLException ;
28
+ import java .time .LocalDate ;
29
+ import java .time .LocalDateTime ;
30
+ import java .time .LocalTime ;
31
+ import java .time .OffsetDateTime ;
32
+ import java .time .OffsetTime ;
33
+ import java .time .format .DateTimeParseException ;
27
34
import org .slf4j .Logger ;
28
35
import org .slf4j .LoggerFactory ;
29
36
@@ -73,7 +80,8 @@ public void setJsonField(final ResultSet resultSet, final int colIndex, final Ob
73
80
case DOUBLE , DOUBLE_UNSIGNED -> putDouble (json , columnName , resultSet , colIndex );
74
81
case DECIMAL , DECIMAL_UNSIGNED -> putBigDecimal (json , columnName , resultSet , colIndex );
75
82
case DATE -> putDate (json , columnName , resultSet , colIndex );
76
- case DATETIME , TIMESTAMP -> putTimestamp (json , columnName , resultSet , colIndex );
83
+ case DATETIME -> putTimestamp (json , columnName , resultSet , colIndex );
84
+ case TIMESTAMP -> putTimestampWithTimezone (json , columnName , resultSet , colIndex );
77
85
case TIME -> putTime (json , columnName , resultSet , colIndex );
78
86
// The returned year value can either be a java.sql.Short (when yearIsDateType=false)
79
87
// or a java.sql.Date with the date set to January 1st, at midnight (when yearIsDateType=true).
@@ -125,7 +133,8 @@ public void setStatementField(final PreparedStatement preparedStatement,
125
133
case FLOAT , FLOAT_UNSIGNED , DOUBLE , DOUBLE_UNSIGNED -> setDouble (preparedStatement , parameterIndex , value );
126
134
case DECIMAL , DECIMAL_UNSIGNED -> setDecimal (preparedStatement , parameterIndex , value );
127
135
case DATE -> setDate (preparedStatement , parameterIndex , value );
128
- case DATETIME , TIMESTAMP -> setTimestamp (preparedStatement , parameterIndex , value );
136
+ case DATETIME -> setTimestamp (preparedStatement , parameterIndex , value );
137
+ case TIMESTAMP -> setTimestampWithTimezone (preparedStatement , parameterIndex , value );
129
138
case TIME -> setTime (preparedStatement , parameterIndex , value );
130
139
case YEAR , CHAR , VARCHAR , TINYTEXT , TEXT , MEDIUMTEXT , LONGTEXT , ENUM , SET -> setString (preparedStatement , parameterIndex , value );
131
140
case TINYBLOB , BLOB , MEDIUMBLOB , LONGBLOB , BINARY , VARBINARY -> setBinary (preparedStatement , parameterIndex , value );
@@ -168,7 +177,22 @@ public MysqlType getFieldType(final JsonNode field) {
168
177
}
169
178
170
179
@ Override
171
- public JsonSchemaType getJsonType (MysqlType mysqlType ) {
180
+ protected void putDate (final ObjectNode node , final String columnName , final ResultSet resultSet , final int index ) throws SQLException {
181
+ node .put (columnName , DateTimeConverter .convertToDate (getObject (resultSet , index , LocalDate .class )));
182
+ }
183
+
184
+ @ Override
185
+ protected void putTime (final ObjectNode node , final String columnName , final ResultSet resultSet , final int index ) throws SQLException {
186
+ node .put (columnName , DateTimeConverter .convertToTime (getObject (resultSet , index , LocalTime .class )));
187
+ }
188
+
189
+ @ Override
190
+ protected void putTimestamp (final ObjectNode node , final String columnName , final ResultSet resultSet , final int index ) throws SQLException {
191
+ node .put (columnName , DateTimeConverter .convertToTimestamp (getObject (resultSet , index , LocalDateTime .class )));
192
+ }
193
+
194
+ @ Override
195
+ public JsonSchemaType getJsonType (final MysqlType mysqlType ) {
172
196
return switch (mysqlType ) {
173
197
case
174
198
// TINYINT(1) is boolean, but it should have been converted to MysqlType.BOOLEAN in {@link
@@ -179,8 +203,54 @@ public JsonSchemaType getJsonType(MysqlType mysqlType) {
179
203
case NULL -> JsonSchemaType .NULL ;
180
204
// BIT(1) is boolean, but it should have been converted to MysqlType.BOOLEAN in {@link getFieldType}
181
205
case BIT , TINYBLOB , BLOB , MEDIUMBLOB , LONGBLOB , BINARY , VARBINARY , GEOMETRY -> JsonSchemaType .STRING_BASE_64 ;
206
+ case TIME -> JsonSchemaType .STRING_TIME_WITHOUT_TIMEZONE ;
207
+ case DATETIME -> JsonSchemaType .STRING_TIMESTAMP_WITHOUT_TIMEZONE ;
208
+ case TIMESTAMP -> JsonSchemaType .STRING_TIMESTAMP_WITH_TIMEZONE ;
209
+ case DATE -> JsonSchemaType .STRING_DATE ;
182
210
default -> JsonSchemaType .STRING ;
183
211
};
184
212
}
185
213
214
+ @ Override
215
+ protected void setDate (final PreparedStatement preparedStatement , final int parameterIndex , final String value ) throws SQLException {
216
+ try {
217
+ preparedStatement .setObject (parameterIndex , LocalDate .parse (value ));
218
+ } catch (final DateTimeParseException e ) {
219
+ // This is just for backward compatibility for connectors created on versions before PR https://github.com/airbytehq/airbyte/pull/15504
220
+ LOGGER .warn ("Exception occurred while trying to parse value for date column the new way, trying the old way" , e );
221
+ super .setDate (preparedStatement , parameterIndex , value );
222
+ }
223
+ }
224
+
225
+ @ Override
226
+ protected void setTimestamp (PreparedStatement preparedStatement , int parameterIndex , String value ) throws SQLException {
227
+ try {
228
+ preparedStatement .setObject (parameterIndex , LocalDateTime .parse (value ));
229
+ } catch (final DateTimeParseException e ) {
230
+ // This is just for backward compatibility for connectors created on versions before PR https://github.com/airbytehq/airbyte/pull/15504
231
+ LOGGER .warn ("Exception occurred while trying to parse value for datetime column the new way, trying the old way" , e );
232
+ preparedStatement .setObject (parameterIndex , OffsetDateTime .parse (value ));
233
+ }
234
+ }
235
+
236
+ private void setTimestampWithTimezone (final PreparedStatement preparedStatement , final int parameterIndex , final String value ) throws SQLException {
237
+ try {
238
+ preparedStatement .setObject (parameterIndex , OffsetDateTime .parse (value ));
239
+ } catch (final DateTimeParseException e ) {
240
+ // This is just for backward compatibility for connectors created on versions before PR https://github.com/airbytehq/airbyte/pull/15504
241
+ LOGGER .warn ("Exception occurred while trying to parse value for timestamp column the new way, trying the old way" , e );
242
+ preparedStatement .setObject (parameterIndex , LocalDateTime .parse (value ));
243
+ }
244
+ }
245
+
246
+ @ Override
247
+ protected void setTime (final PreparedStatement preparedStatement , final int parameterIndex , final String value ) throws SQLException {
248
+ try {
249
+ preparedStatement .setObject (parameterIndex , LocalTime .parse (value ));
250
+ } catch (final DateTimeParseException e ) {
251
+ LOGGER .warn ("Exception occurred while trying to parse value for time column the new way, trying the old way" , e );
252
+ // This is just for backward compatibility for connectors created on versions before PR https://github.com/airbytehq/airbyte/pull/15504
253
+ super .setTime (preparedStatement , parameterIndex , value );
254
+ }
255
+ }
186
256
}
0 commit comments