Learning/Mysql-example/Database/DBConnectSpecific.cs
2023-05-05 20:58:11 +02:00

303 lines
No EOL
13 KiB
C#

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<UInt64, User> users { get; set; }
public Dictionary<UInt64, Address> 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<UInt64, User> users = new Dictionary<UInt64, User>();
Dictionary<UInt64, Address> addresses = new Dictionary<UInt64, Address>();
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<UInt64, Address>();
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<UInt64, User> oldUsers)
{
List<String> fields = new List<String>();
List<Object> values = new List<Object>();
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<UInt64, User> 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<String> fields = new List<String>();
List<Object> values = new List<Object>();
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<String> fields = new List<String>();
List<Object> values = new List<Object>();
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<String> fields = new List<String>();
List<Object> values = new List<Object>();
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<String>();
values = new List<Object>();
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}'");
}
}
}