public async Task <IUser> Add(IUser user, string email) { try { if (user == null) { throw new ArgumentNullException(nameof(user)); } if (!email.IsValidEmail()) { throw new ArgumentException("Invalid email"); } using var cnn = _createdDbConnection(); cnn.Open(); var transaction = cnn.BeginTransaction(); // Validate username var userId = await cnn.ExecuteScalarAsync($"SELECT UserName FROM User WHERE UserName=@UserName", new { user.UserName }, transaction); if (userId != null) { throw new InvalidConstraintException($"Username already exists: {user.UserName}"); } // Validate email var userEmail = await cnn.ExecuteScalarAsync($"SELECT UserName FROM UserDetails WHERE Email=@Email", new { Email = email.EncryptField(_encryptionKey) }, transaction); if (userEmail != null) { throw new InvalidConstraintException($"Email already exists: {email}"); } // Create User string query = $"INSERT INTO User {_getSqlInsertFields(typeof(User))}"; var res = await cnn.ExecuteAsync(query, user, transaction); if (res == 0) { throw new Exception($"ExecuteAsync failed: {query} [{user.ToJson()}]"); } // Create User Settings query = $"INSERT INTO UserSettings {_getSqlInsertFields(typeof(UserSettings))}"; res = await cnn.ExecuteAsync(query, new UserSettings { UserName = user.UserName }, transaction); if (res == 0) { throw new Exception($"ExecuteAsync failed: {query} [{user.ToJson()}]"); } // Create user details query = $"INSERT INTO UserDetails {_getSqlInsertFields(typeof(UserDetails))}"; var details = new UserDetails { UserName = user.UserName, Email = email }; res = await cnn.ExecuteAsync(query, details.Encrypt(_encryptionKey), transaction); if (res == 0) { throw new Exception($"ExecuteAsync failed: {query} [{user.ToJson()}]"); } transaction.Commit(); var settings = new UserSettings { UserName = user.UserName, MainSettings = new MainSettings { UserId = user.UserName, DefaultBoard = 1, Language = "en-US" }.ToJson(), WindowsSettings = new WindowsSettings { UserId = user.UserName }.ToJson(), AndroidSettings = new AndroidSettings { UserId = user.UserName }.ToJson(), IOSSettings = new IOSSettings { UserId = user.UserName }.ToJson() }; var addedSettings = await UpdateSettings(settings); return(user); } catch (Exception ex) { await _log?.WriteErrorAsync(nameof(UserRepository), nameof(Add), user?.ToJson(), null, ex); throw; } }