@@ -11,8 +11,24 @@ namespace SciSharp.MySQL.Replication.Types
11
11
/// <remarks>
12
12
/// Handles the reading and conversion of MySQL TIMESTAMP values with fractional seconds.
13
13
/// </remarks>
14
- class TimestampV2Type : TimeBaseType , IMySQLDataType
14
+ class TimestampV2Type : TimeBaseType , IMySQLDataType , IColumnMetadataLoader
15
15
{
16
+ // Unix epoch start for MySQL TIMESTAMP (1970-01-01 00:00:00 UTC)
17
+ private static readonly DateTime UnixEpoch = new DateTime ( 1970 , 1 , 1 , 0 , 0 , 0 , DateTimeKind . Utc ) ;
18
+
19
+ /// <summary>
20
+ /// Loads metadata for TIMESTAMP2 type.
21
+ /// </summary>
22
+ /// <param name="columnMetadata">The column metadata object.</param>
23
+ public void LoadMetadataValue ( ColumnMetadata columnMetadata )
24
+ {
25
+ // For TIMESTAMP2, the metadata value represents the fractional seconds precision (0-6)
26
+ columnMetadata . Options = new TimestampV2Options
27
+ {
28
+ FractionalSecondsPrecision = columnMetadata . MetadataValue [ 0 ]
29
+ } ;
30
+ }
31
+
16
32
/// <summary>
17
33
/// Reads a TIMESTAMP2 value from the binary log.
18
34
/// </summary>
@@ -21,11 +37,56 @@ class TimestampV2Type : TimeBaseType, IMySQLDataType
21
37
/// <returns>A DateTime object representing the MySQL TIMESTAMP2 value.</returns>
22
38
public object ReadValue ( ref SequenceReader < byte > reader , ColumnMetadata columnMetadata )
23
39
{
24
- int meta = columnMetadata . MetadataValue [ 0 ] ;
25
- var millis = ( long ) reader . ReadBigEndianInteger ( 4 ) ;
26
- var fsp = ReadFractionalSeconds ( ref reader , meta ) ;
27
- var ticks = millis * 1000 + fsp / 1000 ;
28
- return new DateTime ( ticks ) ;
40
+ // Get the precision from metadata
41
+ int fsp = columnMetadata . Options is TimestampV2Options options ?
42
+ options . FractionalSecondsPrecision : 0 ;
43
+
44
+ // Read the 4-byte seconds part (big-endian integer representing seconds since Unix epoch)
45
+ byte b0 , b1 , b2 , b3 ;
46
+ reader . TryRead ( out b0 ) ;
47
+ reader . TryRead ( out b1 ) ;
48
+ reader . TryRead ( out b2 ) ;
49
+ reader . TryRead ( out b3 ) ;
50
+
51
+ uint secondsSinceEpoch = ( ( uint ) b0 << 24 ) | ( ( uint ) b1 << 16 ) | ( ( uint ) b2 << 8 ) | b3 ;
52
+
53
+ // Start with the base DateTime (seconds part)
54
+ DateTime timestamp = UnixEpoch . AddSeconds ( secondsSinceEpoch ) ;
55
+
56
+ // Read fractional seconds if precision > 0
57
+ if ( fsp > 0 )
58
+ {
59
+ int fractionalValue = ReadFractionalSeconds ( ref reader , fsp ) ;
60
+
61
+ // Calculate microseconds
62
+ int microseconds = 0 ;
63
+ switch ( fsp )
64
+ {
65
+ case 1 : microseconds = fractionalValue * 100000 ; break ;
66
+ case 2 : microseconds = fractionalValue * 10000 ; break ;
67
+ case 3 : microseconds = fractionalValue * 1000 ; break ;
68
+ case 4 : microseconds = fractionalValue * 100 ; break ;
69
+ case 5 : microseconds = fractionalValue * 10 ; break ;
70
+ case 6 : microseconds = fractionalValue ; break ;
71
+ }
72
+
73
+ // Add microsecond precision to the DateTime
74
+ // 1 tick = 100 nanoseconds, 1 microsecond = 10 ticks
75
+ timestamp = timestamp . AddTicks ( microseconds * 10 ) ;
76
+ }
77
+
78
+ return timestamp ;
29
79
}
30
80
}
81
+
82
+ /// <summary>
83
+ /// Options specific to TIMESTAMP2 data type.
84
+ /// </summary>
85
+ class TimestampV2Options
86
+ {
87
+ /// <summary>
88
+ /// Gets or sets the precision of fractional seconds (0-6).
89
+ /// </summary>
90
+ public int FractionalSecondsPrecision { get ; set ; }
91
+ }
31
92
}
0 commit comments