|
| 1 | +using Dotmim.Sync; |
| 2 | +using Dotmim.Sync.Builders; |
| 3 | +using Dotmim.Sync.Manager; |
| 4 | +using Dotmim.Sync.MariaDB; |
| 5 | +using Dotmim.Sync.MariaDB.Builders; |
| 6 | +using Dotmim.Sync.SqlServer; |
| 7 | +using Dotmim.Sync.SqlServer.Builders; |
| 8 | +using Dotmim.Sync.SqlServer.Manager; |
| 9 | +using Microsoft.Data.SqlClient; |
| 10 | +using MySqlConnector; |
| 11 | +using System; |
| 12 | +using System.Collections.Generic; |
| 13 | +using System.Data; |
| 14 | +using System.Data.Common; |
| 15 | +using System.Linq; |
| 16 | +using System.Text; |
| 17 | +using System.Threading.Tasks; |
| 18 | + |
| 19 | +namespace CustomProvider |
| 20 | +{ |
| 21 | + |
| 22 | + /// <summary> |
| 23 | + /// Use this provider if your client database does not need to upload any data to the server. |
| 24 | + /// This provider does not create any triggers / tracking tables and only 3 stored proc / tables |
| 25 | + /// If your client database is not readonly, any changes from server will overwrite client changes |
| 26 | + /// </summary> |
| 27 | + public class MariaDBSyncDownloadOnlyProvider : MariaDBSyncProvider |
| 28 | + { |
| 29 | + public MariaDBSyncDownloadOnlyProvider() { } |
| 30 | + public MariaDBSyncDownloadOnlyProvider(string connectionString) : base(connectionString) { } |
| 31 | + public MariaDBSyncDownloadOnlyProvider(MySqlConnectionStringBuilder builder) : base(builder) { } |
| 32 | + |
| 33 | + public override DbSyncAdapter GetSyncAdapter(SyncTable tableDescription, ParserName tableName, ParserName trackingTableName, SyncSetup setup) |
| 34 | + => new MariaDBDownloadOnlySyncAdapter(tableDescription, tableName, trackingTableName, setup); |
| 35 | + |
| 36 | + public override DbTableBuilder GetTableBuilder(SyncTable tableDescription, ParserName tableName, ParserName trackingTableName, SyncSetup setup) |
| 37 | + => new MariaDBDownloadOnlyTableBuilder(tableDescription, tableName, trackingTableName, setup); |
| 38 | + } |
| 39 | + |
| 40 | + /// <summary> |
| 41 | + /// Table builder builds table, tracking tables, triggers, stored proc, types |
| 42 | + /// </summary> |
| 43 | + public class MariaDBDownloadOnlyTableBuilder : MariaDBTableBuilder |
| 44 | + { |
| 45 | + public MariaDBDownloadOnlyTableBuilder(SyncTable tableDescription, ParserName tableName, ParserName trackingTableName, SyncSetup setup) |
| 46 | + : base(tableDescription, tableName, trackingTableName, setup) { } |
| 47 | + |
| 48 | + public override Task<DbCommand> GetCreateStoredProcedureCommandAsync(DbStoredProcedureType storedProcedureType, SyncFilter filter, DbConnection connection, DbTransaction transaction) |
| 49 | + => Task.FromResult<DbCommand>(null); |
| 50 | + public override Task<DbCommand> GetCreateTrackingTableCommandAsync(DbConnection connection, DbTransaction transaction) |
| 51 | + => Task.FromResult<DbCommand>(null); |
| 52 | + public override Task<DbCommand> GetCreateTriggerCommandAsync(DbTriggerType triggerType, DbConnection connection, DbTransaction transaction) |
| 53 | + => Task.FromResult<DbCommand>(null); |
| 54 | + public override Task<DbCommand> GetDropTrackingTableCommandAsync(DbConnection connection, DbTransaction transaction) |
| 55 | + => Task.FromResult<DbCommand>(null); |
| 56 | + public override Task<DbCommand> GetDropTriggerCommandAsync(DbTriggerType triggerType, DbConnection connection, DbTransaction transaction) |
| 57 | + => Task.FromResult<DbCommand>(null); |
| 58 | + public override Task<DbCommand> GetExistsTrackingTableCommandAsync(DbConnection connection, DbTransaction transaction) |
| 59 | + => Task.FromResult<DbCommand>(null); |
| 60 | + public override Task<DbCommand> GetExistsTriggerCommandAsync(DbTriggerType triggerType, DbConnection connection, DbTransaction transaction) |
| 61 | + => Task.FromResult<DbCommand>(null); |
| 62 | + public override Task<DbCommand> GetRenameTrackingTableCommandAsync(ParserName oldTableName, DbConnection connection, DbTransaction transaction) |
| 63 | + => Task.FromResult<DbCommand>(null); |
| 64 | + } |
| 65 | + |
| 66 | + /// <summary> |
| 67 | + /// Sync Adapter gets and executes commands |
| 68 | + /// </summary> |
| 69 | + public class MariaDBDownloadOnlySyncAdapter : MariaDBSyncAdapter |
| 70 | + { |
| 71 | + private ParserName tableName; |
| 72 | + |
| 73 | + public MariaDBDownloadOnlySyncAdapter(SyncTable tableDescription, ParserName tableName, ParserName trackingName, SyncSetup setup) |
| 74 | + : base(tableDescription, tableName, trackingName, setup) |
| 75 | + { |
| 76 | + this.tableName = tableName; |
| 77 | + } |
| 78 | + |
| 79 | + /// <summary> |
| 80 | + /// Returning null for all non used commands (from case default) |
| 81 | + /// </summary> |
| 82 | + public override DbCommand GetCommand(DbCommandType nameType, SyncFilter filter) |
| 83 | + { |
| 84 | + var command = new MySqlCommand(); |
| 85 | + switch (nameType) |
| 86 | + { |
| 87 | + case DbCommandType.UpdateRow: |
| 88 | + case DbCommandType.InitializeRow: |
| 89 | + return CreateUpdateCommand(); |
| 90 | + case DbCommandType.DeleteRow: |
| 91 | + return CreateDeleteCommand(); |
| 92 | + case DbCommandType.DisableConstraints: |
| 93 | + command.CommandType = CommandType.Text; |
| 94 | + command.CommandText = this.MySqlObjectNames.GetCommandName(DbCommandType.DisableConstraints, filter); |
| 95 | + break; |
| 96 | + case DbCommandType.EnableConstraints: |
| 97 | + command.CommandType = CommandType.Text; |
| 98 | + command.CommandText = this.MySqlObjectNames.GetCommandName(DbCommandType.EnableConstraints, filter); |
| 99 | + break; |
| 100 | + case DbCommandType.Reset: |
| 101 | + command.CommandType = CommandType.StoredProcedure; |
| 102 | + command.CommandText = this.MySqlObjectNames.GetStoredProcedureCommandName(DbStoredProcedureType.Reset, filter); |
| 103 | + break; |
| 104 | + default: |
| 105 | + return null; |
| 106 | + } |
| 107 | + |
| 108 | + return command; |
| 109 | + } |
| 110 | + |
| 111 | + public override Task AddCommandParametersAsync(DbCommandType commandType, DbCommand command, DbConnection connection, DbTransaction transaction = null, SyncFilter filter = null) |
| 112 | + { |
| 113 | + |
| 114 | + if (command == null) |
| 115 | + return Task.CompletedTask; |
| 116 | + |
| 117 | + if (command.Parameters != null && command.Parameters.Count > 0) |
| 118 | + return Task.CompletedTask; |
| 119 | + |
| 120 | + switch (commandType) |
| 121 | + { |
| 122 | + case DbCommandType.DeleteRow: |
| 123 | + this.SetDeleteRowParameters(command); |
| 124 | + return Task.CompletedTask; ; |
| 125 | + case DbCommandType.UpdateRow: |
| 126 | + case DbCommandType.InitializeRow: |
| 127 | + this.SetUpdateRowParameters(command); |
| 128 | + return Task.CompletedTask; ; |
| 129 | + default: |
| 130 | + break; |
| 131 | + } |
| 132 | + |
| 133 | + return base.AddCommandParametersAsync(commandType, command, connection, transaction, filter); |
| 134 | + } |
| 135 | + |
| 136 | + private MySqlCommand CreateUpdateCommand() |
| 137 | + { |
| 138 | + var mySqlCommand = new MySqlCommand(); |
| 139 | + var stringBuilder = new StringBuilder(); |
| 140 | + var hasMutableColumns = this.TableDescription.GetMutableColumns(false).Any(); |
| 141 | + |
| 142 | + var selectAllColumnsString = new StringBuilder(); |
| 143 | + var setUpdateAllColumnsString = new StringBuilder(); |
| 144 | + |
| 145 | + string empty = string.Empty; |
| 146 | + foreach (var mutableColumn in this.TableDescription.GetMutableColumnsWithPrimaryKeys()) |
| 147 | + { |
| 148 | + var mutableColumnName = ParserName.Parse(mutableColumn, "`").Quoted().ToString(); |
| 149 | + var parameterColumnName = ParserName.Parse(mutableColumn, "`").Unquoted().Normalized().ToString(); |
| 150 | + |
| 151 | + selectAllColumnsString.Append($"{empty}@{parameterColumnName} as {mutableColumnName}"); |
| 152 | + setUpdateAllColumnsString.Append($"{empty}{mutableColumnName}=`side`.{mutableColumnName}"); |
| 153 | + empty = ", "; |
| 154 | + } |
| 155 | + |
| 156 | + stringBuilder.AppendLine($"INSERT INTO {tableName.Quoted()}"); |
| 157 | + stringBuilder.AppendLine($"SELECT * FROM (SELECT {selectAllColumnsString}) as `side`"); |
| 158 | + if (hasMutableColumns) |
| 159 | + { |
| 160 | + stringBuilder.AppendLine($"ON DUPLICATE KEY"); |
| 161 | + stringBuilder.AppendLine($"UPDATE {setUpdateAllColumnsString};"); |
| 162 | + } |
| 163 | + |
| 164 | + mySqlCommand.CommandText = stringBuilder.ToString(); |
| 165 | + return mySqlCommand; |
| 166 | + } |
| 167 | + |
| 168 | + |
| 169 | + private MySqlCommand CreateDeleteCommand() |
| 170 | + { |
| 171 | + var mySqlCommand = new MySqlCommand(); |
| 172 | + var stringBuilder = new StringBuilder(); |
| 173 | + |
| 174 | + stringBuilder.AppendLine($"DELETE FROM {this.tableName.Quoted()} WHERE"); |
| 175 | + stringBuilder.AppendLine($"{MariaDBManagementUtils.WhereColumnAndParameters(this.TableDescription.GetPrimaryKeysColumns(), "", "@")};"); |
| 176 | + |
| 177 | + mySqlCommand.CommandText = stringBuilder.ToString(); |
| 178 | + return mySqlCommand; |
| 179 | + } |
| 180 | + |
| 181 | + private void SetUpdateRowParameters(DbCommand command) |
| 182 | + { |
| 183 | + DbParameter p; |
| 184 | + |
| 185 | + foreach (var column in this.TableDescription.Columns.Where(c => !c.IsReadOnly)) |
| 186 | + { |
| 187 | + var columnName = ParserName.Parse(column, "`").Unquoted().Normalized().ToString(); |
| 188 | + |
| 189 | + p = command.CreateParameter(); |
| 190 | + p.ParameterName = $"@{columnName}"; |
| 191 | + p.DbType = column.GetDbType(); |
| 192 | + p.SourceColumn = column.ColumnName; |
| 193 | + command.Parameters.Add(p); |
| 194 | + } |
| 195 | + |
| 196 | + p = command.CreateParameter(); |
| 197 | + p.ParameterName = "@row_count"; |
| 198 | + p.DbType = DbType.Int32; |
| 199 | + command.Parameters.Add(p); |
| 200 | + |
| 201 | + } |
| 202 | + |
| 203 | + private void SetDeleteRowParameters(DbCommand command) |
| 204 | + { |
| 205 | + DbParameter p; |
| 206 | + |
| 207 | + foreach (var column in this.TableDescription.GetPrimaryKeysColumns().Where(c => !c.IsReadOnly)) |
| 208 | + { |
| 209 | + var quotedColumn = ParserName.Parse(column, "`").Unquoted().Normalized().ToString(); |
| 210 | + |
| 211 | + p = command.CreateParameter(); |
| 212 | + p.ParameterName = $"@{quotedColumn}"; |
| 213 | + p.DbType = column.GetDbType(); |
| 214 | + p.SourceColumn = column.ColumnName; |
| 215 | + command.Parameters.Add(p); |
| 216 | + } |
| 217 | + |
| 218 | + } |
| 219 | + |
| 220 | + |
| 221 | + } |
| 222 | +} |
0 commit comments