Skip to content

Commit 1bbf30f

Browse files
committed
Refactor Parsing
Improve MySql parsing
1 parent 52e0ae4 commit 1bbf30f

40 files changed

+930
-2207
lines changed

Projects/Dotmim.Sync.Core/Dotmim.Sync.Core.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<VersionSuffix>$(VersionSuffix)</VersionSuffix>
2020
<Version>0.9.2</Version>
2121
<Version Condition=" '$(VersionSuffix)' != '' ">$(Version)-$(VersionSuffix)</Version>
22-
<LangVersion>8.0</LangVersion>
22+
<LangVersion>9.0</LangVersion>
2323
<ApplicationIcon>favicon.ico</ApplicationIcon>
2424
<PackageIcon>packageIcon.png</PackageIcon>
2525
<PublishRepositoryUrl>true</PublishRepositoryUrl>

Projects/Dotmim.Sync.Core/Manager/DbMetadata.cs

Lines changed: 16 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -8,176 +8,58 @@ namespace Dotmim.Sync.Manager
88
{
99
public abstract class DbMetadata
1010
{
11+
1112
/// <summary>
1213
/// Validate if a column definition is actualy supported by the provider
1314
/// </summary>
1415
public abstract bool IsValid(SyncColumn columnDefinition);
1516

1617
/// <summary>
17-
/// Get the datastore type name from a DbType for generating scripts
18-
/// </summary>
19-
public abstract string GetStringFromDbType(DbType dbType, int maxLength);
20-
21-
/// <summary>
22-
/// Get the datastore type name from a provider dbType for generating scripts
23-
/// </summary>
24-
public abstract string GetStringFromOwnerDbType(object ownerType);
25-
26-
/// <summary>
27-
/// Get the datastore precision / scale / length string for generating scripts
28-
/// </summary>
29-
public abstract string GetPrecisionStringFromDbType(DbType dbType, int maxLength, byte precision, byte scale);
30-
31-
/// <summary>
32-
/// Get the datastore precision / scale / length string for generating scripts
33-
/// </summary>
34-
public abstract string GetPrecisionStringFromOwnerDbType(object dbType, int maxLength, byte precision, byte scale);
35-
36-
/// <summary>
37-
/// Get the datastore precision / scale / length for DbParameter
38-
/// </summary>
39-
public abstract (byte precision, byte scale) GetPrecisionFromOwnerDbType(object dbType, byte precision, byte scale);
40-
41-
/// <summary>
42-
/// Get the datastore precision / scale for DbParameter
43-
/// </summary>
44-
public abstract (byte precision, byte scale) GetPrecisionFromDbType(DbType dbType, byte precision, byte scale);
45-
46-
/// <summary>
47-
/// Get the datastore MaxLength for DbParameter
18+
/// Gets and validate a max length issued from the database definition
4819
/// </summary>
49-
public abstract Int32 GetMaxLengthFromDbType(DbType dbType, Int32 maxLength);
20+
public abstract int GetMaxLength(SyncColumn columnDefinition);
5021

5122
/// <summary>
52-
/// Get the datastore maxLength for DbParameter
23+
/// Get the native datastore DbType (that's why we return object instead of SqlDbType or SqliteDbType or MySqlDbType)
5324
/// </summary>
54-
public abstract Int32 GetMaxLengthFromOwnerDbType(object dbType, Int32 maxLength);
25+
public abstract object GetOwnerDbType(SyncColumn columnDefinition);
5526

5627
/// <summary>
5728
/// Get a DbType from a datastore type name
5829
/// </summary>
59-
public abstract DbType ValidateDbType(string typeName, bool isUnsigned, bool isUnicode, long maxLength);
60-
61-
/// <summary>
62-
/// Get a datastore DbType from a datastore type name
63-
/// </summary>
64-
public abstract object ValidateOwnerDbType(string typeName, bool isUnsigned, bool isUnicode, long maxLength);
30+
public abstract DbType GetDbType(SyncColumn columnDefinition);
6531

6632
/// <summary>
67-
/// Gets and validate a max length issued from the database definition
68-
/// </summary>
69-
public abstract int ValidateMaxLength(string typeName, bool isUnsigned, bool isUnicode, long maxLength);
70-
71-
/// <summary>
72-
/// Gets the corresponding DbType from a owner dbtype
73-
/// </summary>
74-
public abstract object GetOwnerDbTypeFromDbType(DbType dbType);
75-
76-
/// <summary>
77-
/// Get a managed type from a datastore dbType
33+
/// Validate if a column is readonly or not
7834
/// </summary>
79-
public abstract Type ValidateType(object ownerType);
35+
/// <param name="columnDefinition"></param>
36+
/// <returns></returns>
37+
public abstract bool IsReadonly(SyncColumn columnDefinition);
8038

8139
/// <summary>
8240
/// Check if a type name is a numeric type
8341
/// </summary>
84-
public abstract bool IsNumericType(string typeName);
85-
86-
/// <summary>
87-
/// Check if a type name is a text type
88-
/// </summary>
89-
public abstract bool IsTextType(string typeName);
42+
public abstract bool IsNumericType(SyncColumn columnDefinition);
9043

9144
/// <summary>
9245
/// Check if a type name support scale
9346
/// </summary>
94-
public abstract bool SupportScale(string typeName);
47+
public abstract bool IsSupportingScale(SyncColumn columnDefinition);
9548

9649
/// <summary>
9750
/// Get precision and scale from a SchemaColumn
9851
/// </summary>
99-
public abstract (byte precision, byte scale) ValidatePrecisionAndScale(SyncColumn columnDefinition);
52+
public abstract (byte precision, byte scale) GetPrecisionAndScale(SyncColumn columnDefinition);
10053

10154
/// <summary>
10255
/// Get precision if supported (MySql supports int(10))
10356
/// </summary>
104-
public abstract byte ValidatePrecision(SyncColumn columnDefinition);
105-
106-
107-
/// <summary>
108-
/// Validate if a column is readonly or not
109-
/// </summary>
110-
/// <param name="columnDefinition"></param>
111-
/// <returns></returns>
112-
public abstract bool ValidateIsReadonly(SyncColumn columnDefinition);
57+
public abstract byte GetPrecision(SyncColumn columnDefinition);
11358

11459
/// <summary>
115-
/// Returns the corresponding Owner DbType. Because it could be lower case, we should handle it
60+
/// Get a managed type from a datastore dbType
11661
/// </summary>
117-
public object TryGetOwnerDbType(string ownerDbType, DbType fallbackDbType, bool isUnsigned, bool isUnicode, long maxLength, string fromProviderType, string ownerProviderType)
118-
{
119-
// We MUST check if we are from the same provider (if it's mysql or oracle, we fallback on dbtype
120-
if (!string.IsNullOrEmpty(ownerDbType) && fromProviderType == ownerProviderType)
121-
return ValidateOwnerDbType(ownerDbType, isUnsigned, isUnicode, maxLength);
122-
123-
// if it's not the same provider, fallback on DbType instead.
124-
return GetOwnerDbTypeFromDbType(fallbackDbType);
125-
}
126-
127-
public string TryGetOwnerDbTypeString(string originalDbType, DbType fallbackDbType, bool isUnsigned, bool isUnicode, long maxLength, string fromProviderType, string ownerProviderType)
128-
{
129-
// We MUST check if we are from the same provider (if it's mysql or oracle, we fallback on dbtype
130-
if (!String.IsNullOrEmpty(originalDbType) && fromProviderType == ownerProviderType)
131-
{
132-
Object ownedDbType = ValidateOwnerDbType(originalDbType, isUnsigned, isUnicode, maxLength);
133-
return GetStringFromOwnerDbType(ownedDbType);
134-
}
135-
136-
// if it's not the same provider, fallback on DbType instead.
137-
return GetStringFromDbType(fallbackDbType, Convert.ToInt32(maxLength));
138-
}
139-
140-
public string TryGetOwnerDbTypePrecision(string originalDbType, DbType fallbackDbType, bool isUnsigned, bool isUnicode, int maxLength, byte precision, byte scale, string fromProviderType, string ownerProviderType)
141-
{
142-
// We MUST check if we are from the same provider (if it's mysql or oracle, we fallback on dbtype
143-
if (!String.IsNullOrEmpty(originalDbType) && fromProviderType == ownerProviderType)
144-
{
145-
object ownedDbType = ValidateOwnerDbType(originalDbType, isUnsigned, isUnicode, maxLength);
146-
return GetPrecisionStringFromOwnerDbType(ownedDbType, maxLength, precision, scale);
147-
}
148-
149-
// if it's not the same provider, fallback on DbType instead.
150-
return GetPrecisionStringFromDbType(fallbackDbType, maxLength, precision, scale);
151-
}
152-
153-
public (byte precision, byte scale) TryGetOwnerPrecisionAndScale(string originalDbType, DbType fallbackDbType, bool isUnsigned, bool isUnicode, long maxLength, byte precision, byte scale, string fromProviderType, string ownerProviderType)
154-
{
155-
// We MUST check if we are from the same provider (if it's mysql or oracle, we fallback on dbtype
156-
if (!String.IsNullOrEmpty(originalDbType) && fromProviderType == ownerProviderType)
157-
{
158-
Object ownedDbType = ValidateOwnerDbType(originalDbType, isUnsigned, isUnicode, maxLength);
159-
return GetPrecisionFromOwnerDbType(ownedDbType, precision, scale);
160-
}
161-
162-
// if it's not the same provider, fallback on DbType instead.
163-
return GetPrecisionFromDbType(fallbackDbType, precision, scale);
164-
165-
}
166-
167-
public int TryGetOwnerMaxLength(string originalDbType, DbType fallbackDbType, bool isUnsigned, bool isUnicode, int maxLength, string fromProviderType, string ownerProviderType)
168-
{
169-
// We MUST check if we are from the same provider (if it's mysql or oracle, we fallback on dbtype
170-
if (!String.IsNullOrEmpty(originalDbType) && fromProviderType == ownerProviderType)
171-
{
172-
Object ownedDbType = ValidateOwnerDbType(originalDbType, isUnsigned, isUnicode, maxLength);
173-
return GetMaxLengthFromOwnerDbType(ownedDbType, maxLength);
174-
}
175-
176-
// if it's not the same provider, fallback on DbType instead.
177-
return GetMaxLengthFromDbType(fallbackDbType, maxLength);
178-
179-
}
180-
62+
public abstract Type GetType(SyncColumn columnDefinition);
18163

18264
}
18365
}

Projects/Dotmim.Sync.Core/Orchestrators/BaseOrchestrator.Schema.cs

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@ private void FillSyncTableWithColumns(SetupTable setupTable, SyncTable schemaTab
155155
if (schemaTable.Columns.Count > 0)
156156
schemaTable.Columns.Clear();
157157

158-
159158
IEnumerable<SyncColumn> lstColumns;
160159

161160
// Validate columns list from setup table if any
@@ -184,7 +183,7 @@ private void FillSyncTableWithColumns(SetupTable setupTable, SyncTable schemaTab
184183
{
185184
// First of all validate if the column is currently supported
186185
if (!this.Provider.GetMetadata().IsValid(column))
187-
throw new UnsupportedColumnTypeException(column.ColumnName, column.OriginalTypeName, this.Provider.GetProviderTypeName());
186+
throw new UnsupportedColumnTypeException(setupTable.GetFullName(), column.ColumnName, column.OriginalTypeName, this.Provider.GetProviderTypeName()); ;
188187

189188
var columnNameLower = column.ColumnName.ToLowerInvariant();
190189
if (columnNameLower == "sync_scope_id"
@@ -197,62 +196,58 @@ private void FillSyncTableWithColumns(SetupTable setupTable, SyncTable schemaTab
197196
|| columnNameLower == "sync_timestamp"
198197
|| columnNameLower == "sync_row_is_tombstone"
199198
)
200-
throw new UnsupportedColumnNameException(column.ColumnName, column.OriginalTypeName, this.Provider.GetProviderTypeName());
201-
202-
// Validate max length
203-
column.MaxLength = this.Provider.GetMetadata().ValidateMaxLength(column.OriginalTypeName, column.IsUnsigned, column.IsUnicode, column.MaxLength);
204-
205-
// Gets the datastore owner dbType (could be SqlDbtype, MySqlDbType, SqliteDbType, NpgsqlDbType & so on ...)
206-
var datastoreDbType = this.Provider.GetMetadata().ValidateOwnerDbType(column.OriginalTypeName, column.IsUnsigned, column.IsUnicode, column.MaxLength);
207-
208-
// once we have the datastore type, we can have the managed type
209-
var columnType = this.Provider.GetMetadata().ValidateType(datastoreDbType);
199+
throw new UnsupportedColumnNameException(setupTable.GetFullName(), column.ColumnName, column.OriginalTypeName, this.Provider.GetProviderTypeName()); ;
210200

211-
// Set the correct type
212-
column.SetType(columnType);
213-
214-
// and the DbType
215-
column.DbType = (int)this.Provider.GetMetadata().ValidateDbType(column.OriginalTypeName, column.IsUnsigned, column.IsUnicode, column.MaxLength);
201+
// Gets the max length
202+
column.MaxLength = this.Provider.GetMetadata().GetMaxLength(column);
216203

217204
// Gets the owner dbtype (SqlDbType, OracleDbType, MySqlDbType, NpsqlDbType & so on ...)
218205
// Sqlite does not have it's own type, so it's DbType too
219-
column.OriginalDbType = datastoreDbType.ToString();
206+
column.OriginalDbType = this.Provider.GetMetadata().GetOwnerDbType(column).ToString();
207+
208+
// get the downgraded DbType
209+
column.DbType = (int)this.Provider.GetMetadata().GetDbType(column);
220210

221-
// Validate if column should be readonly
222-
column.IsReadOnly = this.Provider.GetMetadata().ValidateIsReadonly(column);
211+
// Gets the column readonly's propertye
212+
column.IsReadOnly = this.Provider.GetMetadata().IsReadonly(column);
223213

224214
// set position ordinal
225215
column.Ordinal = ordinal;
226216
ordinal++;
227217

228218
// Validate the precision and scale properties
229-
if (this.Provider.GetMetadata().IsNumericType(column.OriginalTypeName))
219+
if (this.Provider.GetMetadata().IsNumericType(column))
230220
{
231-
if (this.Provider.GetMetadata().SupportScale(column.OriginalTypeName))
221+
if (this.Provider.GetMetadata().IsSupportingScale(column))
232222
{
233-
var (p, s) = this.Provider.GetMetadata().ValidatePrecisionAndScale(column);
223+
var (p, s) = this.Provider.GetMetadata().GetPrecisionAndScale(column);
234224
column.Precision = p;
235225
column.PrecisionSpecified = true;
236226
column.Scale = s;
237227
column.ScaleSpecified = true;
238228
}
239229
else
240230
{
241-
column.Precision = this.Provider.GetMetadata().ValidatePrecision(column);
231+
column.Precision = this.Provider.GetMetadata().GetPrecision(column);
242232
column.PrecisionSpecified = true;
243233
column.ScaleSpecified = false;
244234
}
245235

246236
}
247237

238+
// Get the managed type
239+
// Important to set it at the end, because we are altering column.DataType here
240+
column.SetType(this.Provider.GetMetadata().GetType(column));
241+
248242
// if setup table has no columns, we add all columns from db
249243
// otherwise check if columns exist in the data source
250244
if (setupTable.Columns == null || setupTable.Columns.Count <= 0 || setupTable.Columns.Contains(column.ColumnName))
251245
schemaTable.Columns.Add(column);
246+
252247
// If column does not allow null value and is not compute
253248
// We will not be able to insert a row, so raise an error
254249
else if (!column.AllowDBNull && !column.IsCompute && !column.IsReadOnly && string.IsNullOrEmpty(column.DefaultValue))
255-
throw new Exception($"Column {column.ColumnName} is not part of your setup. But it seems this columns is mandatory in your data source.");
250+
throw new Exception($"In table {setupTable.GetFullName()}, column {column.ColumnName} is not part of your setup. But it seems this columns is mandatory in your data source.");
256251

257252
}
258253
}
@@ -284,7 +279,7 @@ private async Task SetPrimaryKeysAsync(SyncTable schemaTable, DbTableBuilder tab
284279
|| columnNameLower == "sync_row_is_tombstone"
285280
|| columnNameLower == "last_change_datetime"
286281
)
287-
throw new UnsupportedPrimaryKeyColumnNameException(columnKey.ColumnName, columnKey.OriginalTypeName, this.Provider.GetProviderTypeName());
282+
throw new UnsupportedPrimaryKeyColumnNameException(schemaTable.GetFullName(), columnKey.ColumnName, columnKey.OriginalTypeName, this.Provider.GetProviderTypeName());
288283

289284

290285
schemaTable.PrimaryKeys.Add(columnKey.ColumnName);

Projects/Dotmim.Sync.Core/Orchestrators/BaseOrchestrator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ internal void ReportProgress(SyncContext context, IProgress<ProgressArgs> progre
188188
/// <summary>
189189
/// Open a connection
190190
/// </summary>
191-
[DebuggerStepThrough]
191+
//[DebuggerStepThrough]
192192
internal async Task OpenConnectionAsync(DbConnection connection, CancellationToken cancellationToken)
193193
{
194194
// Make an interceptor when retrying to connect

Projects/Dotmim.Sync.Core/Set/SyncColumn.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ public class SyncColumn : SyncNamedItem<SyncColumn>
7878
[DataMember(Name = "dv", IsRequired = false, EmitDefaultValue = false, Order = 21)]
7979
public string DefaultValue { get; set; }
8080

81+
[DataMember(Name = "ext1", IsRequired = false, EmitDefaultValue = false, Order = 22)]
82+
public string ExtraProperty1 { get; set; }
8183

8284

8385

@@ -140,6 +142,7 @@ public SyncColumn Clone()
140142
clone.Scale = this.Scale;
141143
clone.ScaleSpecified = this.ScaleSpecified;
142144
clone.DefaultValue = this.DefaultValue;
145+
clone.ExtraProperty1 = this.ExtraProperty1;
143146
return clone;
144147
}
145148

@@ -405,7 +408,8 @@ public override bool EqualsByProperties(SyncColumn column)
405408
string.Equals(this.OriginalDbType, column.OriginalDbType, sc) &&
406409
string.Equals(this.OriginalTypeName, column.OriginalTypeName, sc) &&
407410
this.DbType == column.DbType &&
408-
string.Equals(this.DefaultValue, column.DefaultValue, sc);
411+
string.Equals(this.DefaultValue, column.DefaultValue, sc) &&
412+
string.Equals(this.ExtraProperty1, column.ExtraProperty1, sc);
409413

410414
}
411415

0 commit comments

Comments
 (0)