@@ -11,18 +11,130 @@ namespace SciSharp.MySQL.Replication.Types
1111    /// <remarks> 
1212    /// Handles the reading and conversion of MySQL TIME values with fractional seconds. 
1313    /// </remarks> 
14-     class  TimeV2Type  :  IMySQLDataType 
14+     class  TimeV2Type  :  IMySQLDataType ,   IColumnMetadataLoader 
1515    { 
16+         /// <summary> 
17+         /// Loads the fractional seconds precision from the column metadata. 
18+         /// </summary> 
19+         /// <param name="columnMetadata">The column metadata containing the precision value.</param> 
20+         public  void  LoadMetadataValue ( ColumnMetadata  columnMetadata ) 
21+         { 
22+             // For TIME2 type, the metadata value represents the precision of fractional seconds 
23+             // MySQL supports precision values from 0 to 6 (microsecond precision) 
24+             columnMetadata . Options  =  new  TimeV2Options 
25+             { 
26+                 FractionalSecondsPrecision  =  columnMetadata . MetadataValue [ 0 ] 
27+             } ; 
28+         } 
29+ 
1630        /// <summary> 
1731        /// Reads a TIME2 value from the binary log. 
1832        /// </summary> 
1933        /// <param name="reader">The sequence reader containing the bytes to read.</param> 
2034        /// <param name="columnMetadata">Metadata for the column defining fractional second precision.</param> 
21-         /// <returns>An object representing the MySQL TIME2 value.</returns> 
22-         /// <exception cref="NotImplementedException">This method has not yet been implemented.</exception> 
35+         /// <returns>A TimeSpan representing the MySQL TIME2 value.</returns> 
2336        public  object  ReadValue ( ref  SequenceReader < byte >  reader ,  ColumnMetadata  columnMetadata ) 
2437        { 
25-             throw  new  NotImplementedException ( ) ; 
38+             // Get the fractional seconds precision from metadata (0-6) 
39+             int  fsp  =  columnMetadata . Options  is  TimeV2Options  options  ?  options . FractionalSecondsPrecision  :  0 ; 
40+ 
41+             // Read the integer part (3 bytes) 
42+             byte  intPartByte1 ,  intPartByte2 ,  intPartByte3 ; 
43+             reader . TryRead ( out  intPartByte1 ) ; 
44+             reader . TryRead ( out  intPartByte2 ) ; 
45+             reader . TryRead ( out  intPartByte3 ) ; 
46+ 
47+             // Combine into a 24-bit integer, bigendian 
48+             int  intPart  =  ( intPartByte1  <<  16 )  |  ( intPartByte2  <<  8 )  |  intPartByte3 ; 
49+ 
50+             // In MySQL 5.6.4+ TIME2 format: 
51+             // Bit 1 (MSB): Sign bit (1=negative, 0=positive) 
52+             // Bits 2-24: Packed BCD encoding of time value 
53+             bool  isNegative  =  ( ( intPart  &  0x800000 )  ==  0 ) ;  // In MySQL TIME2, 0 is negative, 1 is positive 
54+             
55+             // If negative, apply two's complement 
56+             if  ( isNegative ) 
57+             { 
58+                 intPart  =  ~ intPart  +  1 ; 
59+                 intPart  &=  0x7FFFFF ;  // Keep only the 23 bits for the absolute value 
60+             } 
61+ 
62+             // TIME2 is packed in a special format: 
63+             // Bits 2-13: Hours (12 bits) 
64+             // Bits 14-19: Minutes (6 bits) 
65+             // Bits 20-25: Seconds (6 bits) 
66+             int  hours  =  ( intPart  >>  12 )  &  0x3FF ; 
67+             int  minutes  =  ( intPart  >>  6 )  &  0x3F ; 
68+             int  seconds  =  intPart  &  0x3F ; 
69+ 
70+             // Read fractional seconds if precision > 0 
71+             int  microseconds  =  0 ; 
72+             if  ( fsp  >  0 ) 
73+             { 
74+                 // Calculate bytes needed for the requested precision 
75+                 int  fractionalBytes  =  ( fsp  +  1 )  /  2 ; 
76+                 int  fraction  =  0 ; 
77+ 
78+                 // Read bytes for fractional seconds 
79+                 for  ( int  i  =  0 ;  i  <  fractionalBytes ;  i ++ ) 
80+                 { 
81+                     byte  b ; 
82+                     reader . TryRead ( out  b ) ; 
83+                     fraction  =  ( fraction  <<  8 )  |  b ; 
84+                 } 
85+ 
86+                 // Convert to microseconds based on precision 
87+                 int  scaleFactor  =  1000000 ; 
88+                 switch  ( fsp ) 
89+                 { 
90+                     case  1 :  scaleFactor  =  100000 ;  break ; 
91+                     case  2 :  scaleFactor  =  10000 ;  break ; 
92+                     case  3 :  scaleFactor  =  1000 ;  break ; 
93+                     case  4 :  scaleFactor  =  100 ;  break ; 
94+                     case  5 :  scaleFactor  =  10 ;  break ; 
95+                     case  6 :  scaleFactor  =  1 ;  break ; 
96+                 } 
97+                 
98+                 microseconds  =  fraction  *  scaleFactor ; 
99+             } 
100+ 
101+             // Create TimeSpan 
102+             TimeSpan  result ; 
103+             
104+             if  ( hours  >=  24 ) 
105+             { 
106+                 // For large hour values, convert to days + remaining hours 
107+                 int  days  =  hours  /  24 ; 
108+                 int  remainingHours  =  hours  %  24 ; 
109+                 
110+                 // Create TimeSpan with days, hours, minutes, seconds, ms 
111+                 result  =  new  TimeSpan ( days ,  remainingHours ,  minutes ,  seconds ,  microseconds  /  1000 ) ; 
112+                 
113+                 // Add remaining microseconds as ticks (1 tick = 100 nanoseconds, 1 microsecond = 10 ticks) 
114+                 if  ( microseconds  %  1000  >  0 ) 
115+                 { 
116+                     result  =  result . Add ( TimeSpan . FromTicks ( ( microseconds  %  1000 )  *  10 ) ) ; 
117+                 } 
118+             } 
119+             else 
120+             { 
121+                 // Standard case for hours < 24 
122+                 result  =  new  TimeSpan ( 0 ,  hours ,  minutes ,  seconds ,  microseconds  /  1000 ) ; 
123+                 
124+                 // Add microsecond precision as ticks 
125+                 if  ( microseconds  %  1000  >  0 ) 
126+                 { 
127+                     result  =  result . Add ( TimeSpan . FromTicks ( ( microseconds  %  1000 )  *  10 ) ) ; 
128+                 } 
129+             } 
130+ 
131+             // Apply sign 
132+             return  isNegative  ?  result . Negate ( )  :  result ; 
26133        } 
27134    } 
135+ 
136+     class  TimeV2Options 
137+     { 
138+         public  int  FractionalSecondsPrecision  {  get ;  set ;  }  =  0 ; 
139+     } 
28140} 
0 commit comments