using TelegramBotBase.Interfaces; using TelegramBotBase.Builder.Interfaces; using System; using TelegramBotBase.Base; using TelegramBotBase.Args; using TelegramBotBase.Form; using Microsoft.Data.SqlClient; using System.Data; namespace TelegramBotBase.Extensions.Serializer.Database.MSSQL { public class MSSQLSerializer : IStateMachine { public Type FallbackStateForm { get; set; } public string ConnectionString { get; } public String TablePrefix { get; set; } /// /// Will initialize the state machine. /// /// Path of the file and name where to save the session details. /// Type of Form which will be saved instead of Form which has attribute declared. Needs to be subclass of . /// Declares of the file could be overwritten. public MSSQLSerializer(String ConnectionString, String tablePrefix = "tgb_", Type fallbackStateForm = null) { if (ConnectionString is null) { throw new ArgumentNullException(nameof(ConnectionString)); } this.ConnectionString = ConnectionString; this.TablePrefix = tablePrefix; this.FallbackStateForm = fallbackStateForm; if (this.FallbackStateForm != null && !this.FallbackStateForm.IsSubclassOf(typeof(FormBase))) { throw new ArgumentException("FallbackStateForm is not a subclass of FormBase"); } } public StateContainer LoadFormStates() { var sc = new StateContainer(); using (var connection = new SqlConnection(ConnectionString)) { connection.Open(); var command = connection.CreateCommand(); command.CommandText = "SELECT deviceId, deviceTitle, FormUri, QualifiedName FROM " + TablePrefix + "devices_sessions"; var dataTable = new DataTable(); using (var dataAdapter = new SqlDataAdapter(command)) { dataAdapter.Fill(dataTable); foreach (DataRow r in dataTable.Rows) { var se = new StateEntry() { DeviceId = (long)r["deviceId"], ChatTitle = r["deviceTitle"].ToString(), FormUri = r["FormUri"].ToString(), QualifiedName = r["QualifiedName"].ToString() }; sc.States.Add(se); if (se.DeviceId > 0) { sc.ChatIds.Add(se.DeviceId); } else { sc.GroupIds.Add(se.DeviceId); } var data_command = connection.CreateCommand(); data_command.CommandText = "SELECT [key], value, type FROM " + TablePrefix + "devices_sessions_data WHERE deviceId = @deviceId"; data_command.Parameters.Add(new SqlParameter("@deviceId", r["deviceId"])); var data_table = new DataTable(); using (var dataAdapter2 = new SqlDataAdapter(data_command)) { dataAdapter2.Fill(data_table); foreach (DataRow r2 in data_table.Rows) { var key = r2["key"].ToString(); var type = Type.GetType(r2["type"].ToString()); var value = Newtonsoft.Json.JsonConvert.DeserializeObject(r2["value"].ToString(), type); se.Values.Add(key, value); } } } } connection.Close(); } return sc; } public void SaveFormStates(SaveStatesEventArgs e) { var container = e.States; using (var connection = new SqlConnection(ConnectionString)) { connection.Open(); //Cleanup old Session data var clear_command = connection.CreateCommand(); clear_command.CommandText = $"DELETE FROM {TablePrefix}devices_sessions_data"; clear_command.ExecuteNonQuery(); clear_command.CommandText = $"DELETE FROM {TablePrefix}devices_sessions"; clear_command.ExecuteNonQuery(); //Prepare new session commands var session_command = connection.CreateCommand(); var data_command = connection.CreateCommand(); session_command.CommandText = "INSERT INTO " + TablePrefix + "devices_sessions (deviceId, deviceTitle, FormUri, QualifiedName) VALUES (@deviceId, @deviceTitle, @FormUri, @QualifiedName)"; session_command.Parameters.Add(new SqlParameter("@deviceId", "")); session_command.Parameters.Add(new SqlParameter("@deviceTitle", "")); session_command.Parameters.Add(new SqlParameter("@FormUri", "")); session_command.Parameters.Add(new SqlParameter("@QualifiedName", "")); data_command.CommandText = "INSERT INTO " + TablePrefix + "devices_sessions_data (deviceId, [key], value, type) VALUES (@deviceId, @key, @value, @type)"; data_command.Parameters.Add(new SqlParameter("@deviceId", "")); data_command.Parameters.Add(new SqlParameter("@key", "")); data_command.Parameters.Add(new SqlParameter("@value", "")); data_command.Parameters.Add(new SqlParameter("@type", "")); //Store session data in database foreach (var state in container.States) { session_command.Parameters["@deviceId"].Value = state.DeviceId; session_command.Parameters["@deviceTitle"].Value = state.ChatTitle ?? ""; session_command.Parameters["@FormUri"].Value = state.FormUri; session_command.Parameters["@QualifiedName"].Value = state.QualifiedName; session_command.ExecuteNonQuery(); foreach (var data in state.Values) { data_command.Parameters["@deviceId"].Value = state.DeviceId; data_command.Parameters["@key"].Value = data.Key; var type = data.Value.GetType(); if (type.IsPrimitive || type.Equals(typeof(string))) { data_command.Parameters["@value"].Value = data.Value; } else { data_command.Parameters["@value"].Value = Newtonsoft.Json.JsonConvert.SerializeObject(data.Value); } data_command.Parameters["@type"].Value = type.AssemblyQualifiedName; data_command.ExecuteNonQuery(); } } connection.Close(); } } } }