using MySql.Data.MySqlClient; using Mysql_example.Database.Schema; using Mysql_example.Util; using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Mysql_example.Database { class DBConnectSpecific : DBConnectGeneral { public DBConnectSpecific(){ } public struct usersAndAddressesStruct { public Dictionary users { get; set; } public Dictionary addresses { get; set; } } public usersAndAddressesStruct ReadUsersAndAddresses() { string querry = @$" SELECT users.*, addresses.id As `addr.id`, addresses.user_id AS `addr.user_id`, addresses.first_name As `addr.first_name`, addresses.last_name AS `addr.last_name`, addresses.street AS `addr.street`, addresses.house_number AS `addr.house_number`, addresses.city AS `addr.city`, addresses.postal_code AS `addr.postal_code`, addresses.country AS `addr.country`, addresses.last_updated AS `addr.last_updated` FROM `users` LEFT JOIN `addresses` ON users.id = addresses.user_id; "; if (!this.OpenConnection()) throw new Exception("No Database Connection"); usersAndAddressesStruct result = new usersAndAddressesStruct(); Dictionary users = new Dictionary(); Dictionary addresses = new Dictionary(); MySqlCommand selectCmd = new MySqlCommand(querry, connection); MySqlDataReader dataReader = selectCmd.ExecuteReader(); while (dataReader.Read()) { UInt64 userId = dataReader.GetUInt64("id"); if (users.ContainsKey(userId)) { User user = users[userId]; Address address = ReadAddress(dataReader); user.Addresses[address.Id] = address; addresses[address.Id] = address; if (!dataReader.IsDBNull("billing_address_id") && dataReader.GetUInt64("billing_address_id") == address.Id) user.BillingAdress = address; if (!dataReader.IsDBNull("shipping_address_id") && dataReader.GetUInt64("shipping_address_id") == address.Id) user.ShippingAddress = address; continue; } User readedUser = ReadUser(dataReader); if (!dataReader.IsDBNull("addr.id")) { Address address = ReadAddress(dataReader); readedUser.Addresses[address.Id] = address; addresses[address.Id] = address; if (!dataReader.IsDBNull("billing_address_id") && dataReader.GetUInt64("billing_address_id") == address.Id) readedUser.BillingAdress = address; if (!dataReader.IsDBNull("shipping_address_id") && dataReader.GetUInt64("shipping_address_id") == address.Id) readedUser.ShippingAddress = address; } users.Add(readedUser.Id, readedUser); } CloseConnection(); result.users = users; result.addresses = addresses; return result; } private static User ReadUser(MySqlDataReader reader) { User user = new User(); user.Id = reader.GetUInt64("id"); user.Email = reader.GetString("email"); user.FirstName = reader.GetString("first_name"); user.LastName = reader.GetString("last_name"); user.Birthday = reader.GetDateTime("birthday"); user.LastUpdated = reader.GetDateTime("last_updated"); user.Addresses = new Dictionary(); return user; } private static Address ReadAddress(MySqlDataReader reader) { Address address = new Address(); address.Id = reader.GetUInt64("addr.id"); address.UserID = reader.GetUInt64("addr.user_id"); address.FirstName = reader.GetString("addr.first_name"); address.LastName = reader.GetString("addr.last_name"); address.Street = reader.GetString("addr.street"); address.HouseNumber = reader.GetString("addr.house_number"); address.City = reader.GetString("addr.city"); address.PostalCode = reader.GetString("addr.postal_code"); address.Region = reader.GetString("addr.country"); address.LastUpdated = reader.GetDateTime("addr.last_updated"); return address; } public void UpdateUser(ref User user, Dictionary oldUsers) { List fields = new List(); List values = new List(); if (!oldUsers.ContainsKey(user.Id)) { fields.Add("email"); values.Add(user.Email); fields.Add("first_name"); values.Add(user.FirstName); fields.Add("last_name"); values.Add(user.LastName); fields.Add("birthday"); values.Add(Utility.dateTimeToDatabaseBirthday(user.Birthday)); DateTime createTime = DateTime.Now; user.LastUpdated = createTime; fields.Add("last_updated"); values.Add(Utility.dateTimeToDatabaseTimestamp(createTime)); UInt64 newUserID = Insert("users", fields, values); user.Id = newUserID; } User olduser = oldUsers[user.Id]; if (olduser.Email != user.Email) { fields.Add("email"); values.Add(user.Email); } if (olduser.FirstName != user.FirstName) { fields.Add("first_name"); values.Add(user.FirstName); } if (olduser.LastName != user.LastName) { fields.Add("last_name"); values.Add(user.LastName); } if (olduser.Birthday != user.Birthday) { fields.Add("birthday"); values.Add(Utility.dateTimeToDatabaseBirthday(user.Birthday)); } if (olduser.BillingAdress != user.BillingAdress) { fields.Add("billing_address_id"); values.Add(user.BillingAdress != null ? user.BillingAdress.Id : null); } if (olduser.ShippingAddress != user.ShippingAddress) { fields.Add("shipping_address_id"); values.Add(user.ShippingAddress != null ? user.ShippingAddress.Id : null); } //If no Changes, Do no Databse Call if (fields.Count() == 0) return; //Add Last Updated Field DateTime updateTime = DateTime.Now; fields.Add("last_updated"); values.Add(Utility.dateTimeToDatabaseTimestamp(updateTime)); Update("users", fields, values, $"`id`={user.Id} and `last_updated`='{Utility.dateTimeToDatabaseTimestamp(user.LastUpdated)}'"); return; } public void UpdateAddressesOnUser(ref User user, Dictionary oldUsers) { if (!oldUsers.ContainsKey(user.Id)) { AddAddressesOfNewUser(user); } //Get Diffrences for each Adress and make a Database Call User olduser = oldUsers[user.Id]; foreach (Address newAddress in user.Addresses.Values) { List fields = new List(); List values = new List(); if (!olduser.Addresses.ContainsKey(newAddress.Id)) { AddNewAddressOfUser(newAddress, user); continue; } Address oldAdress = olduser.Addresses[newAddress.Id]; if (oldAdress.FirstName != newAddress.FirstName) fields.Add("first_name"); values.Add(newAddress.FirstName); if (oldAdress.LastName != newAddress.LastName) fields.Add("last_name"); values.Add(newAddress.LastName); if (oldAdress.Street != newAddress.Street) fields.Add("street"); values.Add(newAddress.Street); if (oldAdress.HouseNumber != newAddress.HouseNumber)fields.Add("house_number"); values.Add(newAddress.HouseNumber); if (oldAdress.City != newAddress.City) fields.Add("city"); values.Add(newAddress.City); if (oldAdress.PostalCode != newAddress.PostalCode) fields.Add("postal_code"); values.Add(newAddress.PostalCode); if (oldAdress.Region != newAddress.Region) fields.Add("country"); values.Add(newAddress.Region); //If no Changes, Do no Databse Call if (fields.Count() == 0) continue; //Add Last Updated Field DateTime updateTime = DateTime.Now; fields.Add("last_updated"); values.Add(Utility.dateTimeToDatabaseTimestamp(updateTime)); Update("addresses", fields, values, $"`id`={newAddress.Id} and `last_updated`='{Utility.dateTimeToDatabaseTimestamp(newAddress.LastUpdated)}'"); } foreach (Address deletedAddress in user.deletedAddreses) { Delete("addresses", $"`id`='{deletedAddress.Id}'"); } } private UInt64 AddNewAddressOfUser(Address address, User user) { List fields = new List(); List values = new List(); fields.Add("user_id"); values.Add(user.Id); fields.Add("first_name"); values.Add(address.FirstName); fields.Add("last_name"); values.Add(address.LastName); fields.Add("street"); values.Add(address.Street); fields.Add("house_number"); values.Add(address.HouseNumber); fields.Add("city"); values.Add(address.City); fields.Add("postal_code"); values.Add(address.PostalCode); fields.Add("country"); values.Add(address.Region); DateTime createTime = DateTime.Now; fields.Add("last_updated"); values.Add(Utility.dateTimeToDatabaseTimestamp(createTime)); return Insert("addresses", fields, values); } private void AddAddressesOfNewUser(User user) { List fields = new List(); List values = new List(); foreach (Address address in user.Addresses.Values) { if ( address.FirstName == null || address.LastName == null || address.Street == null || address.City == null || address.PostalCode == null || address.Region == null ) continue; UInt64 addressId = AddNewAddressOfUser(address, user); if (user.BillingAdress == null && user.ShippingAddress == null) continue; fields = new List(); values = new List(); if (user.BillingAdress != null) { fields.Add("billing_address_id"); values.Add(addressId); } if (user.ShippingAddress != null) { fields.Add("shipping_address_id"); values.Add(addressId); } //Add Last Updated Field DateTime updateTime = DateTime.Now; fields.Add("last_updated"); values.Add(Utility.dateTimeToDatabaseTimestamp(updateTime)); Update("users", fields, values, $"`id`={user.Id} and `last_updated`='{Utility.dateTimeToDatabaseTimestamp(user.LastUpdated)}'"); continue; } return; } public void DeleteUser(User user) { foreach (Address address in user.Addresses.Values) { Delete("addresses", $"`id`='{address.Id}'"); } Delete("users", $"`id`='{user.Id}'"); } } }