Skip to content

Commit 2dafd05

Browse files
committed
tried to supprot enum and set
1 parent 4bd8216 commit 2dafd05

11 files changed

+133
-23
lines changed

src/SciSharp.MySQL.Replication/ColumnMetadata.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class ColumnMetadata
2020
/// <summary>
2121
/// Gets or sets the metadata value associated with the column.
2222
/// </summary>
23-
public short MetadataValue { get; set; }
23+
public ushort MetadataValue { get; set; }
2424

2525
/// <summary>
2626
/// Gets or sets the column max value length.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System;
2+
using SciSharp.MySQL.Replication.Types;
3+
4+
namespace SciSharp.MySQL.Replication.Events
5+
{
6+
class EnumTypeTableMetadataInitializer : ITableMetadataInitializer
7+
{
8+
public void InitializeMetadata(TableMetadata metadata)
9+
{
10+
var enumColumnIndex = 0;
11+
12+
foreach (var column in metadata.Columns)
13+
{
14+
if (!IsEnumColumn(column))
15+
continue;
16+
17+
column.EnumValues = metadata.EnumStrValues[enumColumnIndex++];
18+
}
19+
}
20+
21+
private bool IsEnumColumn(ColumnMetadata columnMetadata)
22+
{
23+
if (columnMetadata.Type == ColumnType.ENUM)
24+
return true;
25+
26+
if (columnMetadata.Type != ColumnType.STRING)
27+
return false;
28+
29+
// Len = 1 or 2
30+
return (columnMetadata.MetadataValue & 0xFF) < 3;
31+
}
32+
}
33+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace SciSharp.MySQL.Replication.Events
2+
{
3+
interface ITableMetadataInitializer
4+
{
5+
void InitializeMetadata(TableMetadata tableMetadata);
6+
}
7+
}

src/SciSharp.MySQL.Replication/Events/LogEvent.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ static LogEvent()
6969
DataTypes[(int)ColumnType.DATETIME] = new DateTimeType();
7070
DataTypes[(int)ColumnType.DATETIME_V2] = new DateTimeV2Type();
7171
//DataTypes[(int)ColumnType.TIMESTAMP] = new TimestampType();
72-
//DataTypes[(int)ColumnType.ENUM] = new EnumType();
72+
DataTypes[(int)ColumnType.ENUM] = new EnumType();
73+
DataTypes[(int)ColumnType.SET] = new SetType();
7374
}
7475

7576
/// <summary>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
using SciSharp.MySQL.Replication.Types;
3+
4+
namespace SciSharp.MySQL.Replication.Events
5+
{
6+
class NumericTypeTableMetadataInitializer : ITableMetadataInitializer
7+
{
8+
public void InitializeMetadata(TableMetadata metadata)
9+
{
10+
var numericColumnIndex = 0;
11+
12+
foreach (var column in metadata.Columns)
13+
{
14+
if (!column.Type.IsNumberColumn())
15+
continue;
16+
17+
column.IsUnsigned = metadata.Signedness[numericColumnIndex];
18+
column.NumericColumnIndex = numericColumnIndex;
19+
20+
numericColumnIndex++;
21+
}
22+
}
23+
}
24+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
using SciSharp.MySQL.Replication.Types;
3+
4+
namespace SciSharp.MySQL.Replication.Events
5+
{
6+
class SetTypeTableMetadataInitializer : ITableMetadataInitializer
7+
{
8+
public void InitializeMetadata(TableMetadata metadata)
9+
{
10+
var setColumnIndex = 0;
11+
12+
foreach (var column in metadata.Columns)
13+
{
14+
if (column.Type != ColumnType.SET)
15+
continue;
16+
17+
column.SetValues = metadata.SetStrValues[setColumnIndex];
18+
setColumnIndex++;
19+
}
20+
}
21+
}
22+
}

src/SciSharp.MySQL.Replication/Events/TableMapEvent.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ public sealed class TableMapEvent : LogEvent
5555
/// Gets or sets the metadata of the table.
5656
/// </summary>
5757
public TableMetadata Metadata { get; set; }
58+
59+
private readonly IReadOnlyList<ITableMetadataInitializer> _tableMetadataInitializers = new List<ITableMetadataInitializer>
60+
{
61+
new NumericTypeTableMetadataInitializer(),
62+
new EnumTypeTableMetadataInitializer(),
63+
new SetTypeTableMetadataInitializer()
64+
};
5865

5966
/// <summary>
6067
/// Initializes a new instance of the <see cref="TableMapEvent"/> class.
@@ -100,6 +107,11 @@ protected internal override void DecodeBody(ref SequenceReader<byte> reader, obj
100107

101108
Metadata = ReadTableMetadata(ref reader);
102109

110+
foreach (var tableMetadataInitializer in _tableMetadataInitializers)
111+
{
112+
tableMetadataInitializer.InitializeMetadata(Metadata);
113+
}
114+
103115
foreach (var columnMetadata in Metadata.Columns)
104116
{
105117
var valueTypeIndex = (int)columnMetadata.Type;

src/SciSharp.MySQL.Replication/TableMetadata.cs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,25 +89,16 @@ public void BuildColumnMetadataList(IReadOnlyList<ColumnType> columnTypes, IRead
8989
{
9090
var columnMetadatas = new List<ColumnMetadata>(ColumnNames.Count);
9191

92-
var numericColumnIndex = -1;
93-
9492
for (int i = 0; i < columnTypes.Count; i++)
9593
{
9694
var columnType = columnTypes[i];
97-
var isNumberColumn = columnType.IsNumberColumn();
98-
numericColumnIndex++;
9995

10096
var columnMetadata = new ColumnMetadata
10197
{
10298
Name = ColumnNames[i],
10399
Type = columnType,
104100
CharsetId = ColumnCharsets != null ? ColumnCharsets[i] : 0,
105-
//If the bit is set (1), the column is UNSIGNED; if not set (0), it's SIGNED (default)
106-
IsUnsigned = isNumberColumn ? Signedness[numericColumnIndex] : false,
107-
EnumValues = EnumStrValues != null ? EnumStrValues[i] : null,
108-
SetValues = SetStrValues != null ? SetStrValues[i] : null,
109-
MetadataValue = (short)columnMetadataValues[i],
110-
NumericColumnIndex = isNumberColumn ? numericColumnIndex : -1
101+
MetadataValue = (ushort)columnMetadataValues[i]
111102
};
112103

113104
columnMetadatas.Add(columnMetadata);

src/SciSharp.MySQL.Replication/Types/EnumType.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,37 @@ namespace SciSharp.MySQL.Replication.Types
1111
/// <remarks>
1212
/// Handles the reading and conversion of MySQL ENUM values.
1313
/// </remarks>
14-
class EnumType : IMySQLDataType
14+
class EnumType : IMySQLDataType, IColumnMetadataLoader
1515
{
16+
public void LoadMetadataValue(ColumnMetadata columnMetadata)
17+
{
18+
columnMetadata.MaxLength = columnMetadata.MetadataValue & 0xFF;
19+
}
20+
1621
/// <summary>
1722
/// Reads an ENUM value from the binary log.
1823
/// </summary>
1924
/// <param name="reader">The sequence reader containing the bytes to read.</param>
2025
/// <param name="columnMetadata">Metadata for the column.</param>
2126
/// <returns>An integer representing the index of the ENUM value.</returns>
22-
public object ReadValue(ref SequenceReader<byte> reader, ColumnMetadata columnMetadata)
27+
public virtual object ReadValue(ref SequenceReader<byte> reader, ColumnMetadata columnMetadata)
2328
{
24-
var enumIndex = reader.ReadInteger(2);
29+
var enumIndex = columnMetadata.MaxLength == 1
30+
? reader.TryRead(out byte l) ? (int)l : 0
31+
: reader.TryReadLittleEndian(out short sl) ? (int)sl : 0;
2532

2633
// Out of range check
2734
if (enumIndex >= columnMetadata.EnumValues.Count)
2835
{
2936
return null;
3037
}
3138

32-
return columnMetadata.EnumValues[enumIndex];
39+
if (enumIndex == 0)
40+
{
41+
return string.Empty;
42+
}
43+
44+
return columnMetadata.EnumValues[enumIndex - 1];
3345
}
3446
}
3547
}

src/SciSharp.MySQL.Replication/Types/SetType.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,13 @@ namespace SciSharp.MySQL.Replication.Types
1010
/// <remarks>
1111
/// Handles the reading and conversion of MySQL SET values.
1212
/// </remarks>
13-
class SetType : IMySQLDataType
13+
class SetType : IMySQLDataType, IColumnMetadataLoader
1414
{
15+
public void LoadMetadataValue(ColumnMetadata columnMetadata)
16+
{
17+
columnMetadata.MaxLength = columnMetadata.MetadataValue & 0xFF;
18+
}
19+
1520
/// <summary>
1621
/// Reads a SET value from the binary log.
1722
/// </summary>
@@ -20,18 +25,18 @@ class SetType : IMySQLDataType
2025
/// <returns>A long value representing the MySQL SET value as a bitmap.</returns>
2126
public object ReadValue(ref SequenceReader<byte> reader, ColumnMetadata columnMetadata)
2227
{
23-
var setValue = reader.ReadLong(4);
28+
var flags = reader.ReadLong(columnMetadata.MaxLength);
2429

25-
if (setValue == 0)
30+
if (flags == 0)
2631
{
27-
return 0;
32+
return string.Empty;
2833
}
2934

3035
var setCellValues = new List<string>();
3136

3237
for (int i = 0; i < columnMetadata.SetValues.Count; i++)
3338
{
34-
if ((setValue & (1 << i)) != 0)
39+
if ((flags & (1 << i)) != 0)
3540
{
3641
setCellValues.Add(columnMetadata.SetValues[i]);
3742
}

0 commit comments

Comments
 (0)