From b23a710533803e20daf3b5e450b3281562a38748 Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Sun, 5 Jul 2020 22:57:05 -0400 Subject: [PATCH] implementing TwitterDal --- .../CachedTweetsPostgresDal.cs | 34 +++++++ .../TwitterUserPostgresDal.cs | 74 +++++++++++++- .../BirdsiteLive.DAL/BirdsiteLive.DAL.csproj | 4 + .../Contracts/ICachedTweetsDal.cs | 12 +++ .../Contracts/ITwitterUserDal.cs | 11 ++- .../Base/PostgresTestingBase.cs | 27 +++++ .../DbInitializerPostgresDalTests.cs | 24 +---- .../TwitterUserPostgresDalTests.cs | 99 +++++++++++++++++++ 8 files changed, 258 insertions(+), 27 deletions(-) create mode 100644 src/DataAccessLayers/BirdsiteLive.DAL.Postgres/DataAccessLayers/CachedTweetsPostgresDal.cs create mode 100644 src/DataAccessLayers/BirdsiteLive.DAL/Contracts/ICachedTweetsDal.cs create mode 100644 src/Tests/BirdsiteLive.DAL.Postgres.Tests/DataAccessLayers/Base/PostgresTestingBase.cs create mode 100644 src/Tests/BirdsiteLive.DAL.Postgres.Tests/DataAccessLayers/TwitterUserPostgresDalTests.cs diff --git a/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/DataAccessLayers/CachedTweetsPostgresDal.cs b/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/DataAccessLayers/CachedTweetsPostgresDal.cs new file mode 100644 index 0000000..3251c41 --- /dev/null +++ b/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/DataAccessLayers/CachedTweetsPostgresDal.cs @@ -0,0 +1,34 @@ +using System.Threading.Tasks; +using BirdsiteLive.DAL.Contracts; +using BirdsiteLive.DAL.Postgres.DataAccessLayers.Base; +using BirdsiteLive.DAL.Postgres.Settings; +using BirdsiteLive.DAL.Postgres.Tools; +using Tweetinvi.Models; + +namespace BirdsiteLive.DAL.Postgres.DataAccessLayers +{ + public class CachedTweetsPostgresDal : PostgresBase, ICachedTweetsDal + { + #region Ctor + public CachedTweetsPostgresDal(PostgresSettings settings, PostgresTools tools) : base(settings) + { + + } + #endregion + + public Task AddTweetAsync(long tweetId, int userId, ITweet tweet) + { + throw new System.NotImplementedException(); + } + + public Task GetTweetAsync(long tweetId) + { + throw new System.NotImplementedException(); + } + + public Task DeleteTweetAsync(long tweetId) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/DataAccessLayers/TwitterUserPostgresDal.cs b/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/DataAccessLayers/TwitterUserPostgresDal.cs index 2058bf3..94e1087 100644 --- a/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/DataAccessLayers/TwitterUserPostgresDal.cs +++ b/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/DataAccessLayers/TwitterUserPostgresDal.cs @@ -1,9 +1,77 @@ -using BirdsiteLive.DAL.Contracts; +using System; +using System.Linq; +using System.Threading.Tasks; +using BirdsiteLive.DAL.Contracts; +using BirdsiteLive.DAL.Models; +using BirdsiteLive.DAL.Postgres.DataAccessLayers.Base; +using BirdsiteLive.DAL.Postgres.Settings; +using BirdsiteLive.DAL.Postgres.Tools; +using Dapper; +using Npgsql; namespace BirdsiteLive.DAL.Postgres.DataAccessLayers { - public class TwitterUserPostgresDal : ITwitterUserDal + public class TwitterUserPostgresDal : PostgresBase, ITwitterUserDal { - + #region Ctor + public TwitterUserPostgresDal(PostgresSettings settings) : base(settings) + { + + } + #endregion + + public async Task CreateTwitterUserAsync(string acct, long lastTweetPostedId) + { + using (var dbConnection = Connection) + { + dbConnection.Open(); + + await dbConnection.ExecuteAsync( + $"INSERT INTO {_settings.TwitterUserTableName} (acct,lastTweetPostedId,lastTweetSynchronizedForAllFollowersId) VALUES(@acct,@lastTweetPostedId,@lastTweetSynchronizedForAllFollowersId)", + new { acct = acct, lastTweetPostedId = lastTweetPostedId, lastTweetSynchronizedForAllFollowersId = lastTweetPostedId }); + } + } + + public async Task GetTwitterUserAsync(string acct) + { + var query = $"SELECT * FROM {_settings.TwitterUserTableName} WHERE acct = @acct"; + + using (var dbConnection = Connection) + { + dbConnection.Open(); + + var result = (await dbConnection.QueryAsync(query, new { acct = acct })).FirstOrDefault(); + return result; + } + } + + public Task GetAllTwitterUsersAsync() + { + throw new System.NotImplementedException(); + } + + public async Task UpdateTwitterUserAsync(int id, long lastTweetPostedId, long lastTweetSynchronizedForAllFollowersId) + { + if(id == default) throw new ArgumentException("id"); + if(lastTweetPostedId == default) throw new ArgumentException("lastTweetPostedId"); + if(lastTweetSynchronizedForAllFollowersId == default) throw new ArgumentException("lastTweetSynchronizedForAllFollowersId"); + + var query = $"UPDATE {_settings.TwitterUserTableName} SET lastTweetPostedId = {lastTweetPostedId}, lastTweetSynchronizedForAllFollowersId = {lastTweetSynchronizedForAllFollowersId} WHERE id = {id}"; + + using (var dbConnection = Connection) + using (var cmd = new NpgsqlCommand(query, dbConnection)) + { + dbConnection.Open(); + await cmd.ExecuteNonQueryAsync(); + } + } + + public Task DeleteTwitterUserAsync(string acct) + { + + + + throw new System.NotImplementedException(); + } } } \ No newline at end of file diff --git a/src/DataAccessLayers/BirdsiteLive.DAL/BirdsiteLive.DAL.csproj b/src/DataAccessLayers/BirdsiteLive.DAL/BirdsiteLive.DAL.csproj index 9f5c4f4..84e0bf0 100644 --- a/src/DataAccessLayers/BirdsiteLive.DAL/BirdsiteLive.DAL.csproj +++ b/src/DataAccessLayers/BirdsiteLive.DAL/BirdsiteLive.DAL.csproj @@ -4,4 +4,8 @@ netstandard2.0 + + + + diff --git a/src/DataAccessLayers/BirdsiteLive.DAL/Contracts/ICachedTweetsDal.cs b/src/DataAccessLayers/BirdsiteLive.DAL/Contracts/ICachedTweetsDal.cs new file mode 100644 index 0000000..d1214a5 --- /dev/null +++ b/src/DataAccessLayers/BirdsiteLive.DAL/Contracts/ICachedTweetsDal.cs @@ -0,0 +1,12 @@ +using System.Threading.Tasks; +using Tweetinvi.Models; + +namespace BirdsiteLive.DAL.Contracts +{ + public interface ICachedTweetsDal + { + Task AddTweetAsync(long tweetId, int userId, ITweet tweet); + Task GetTweetAsync(long tweetId); + Task DeleteTweetAsync(long tweetId); + } +} \ No newline at end of file diff --git a/src/DataAccessLayers/BirdsiteLive.DAL/Contracts/ITwitterUserDal.cs b/src/DataAccessLayers/BirdsiteLive.DAL/Contracts/ITwitterUserDal.cs index 195b49b..e0050fd 100644 --- a/src/DataAccessLayers/BirdsiteLive.DAL/Contracts/ITwitterUserDal.cs +++ b/src/DataAccessLayers/BirdsiteLive.DAL/Contracts/ITwitterUserDal.cs @@ -1,7 +1,14 @@ -namespace BirdsiteLive.DAL.Contracts +using System.Threading.Tasks; +using BirdsiteLive.DAL.Models; + +namespace BirdsiteLive.DAL.Contracts { public interface ITwitterUserDal { - + Task CreateTwitterUserAsync(string acct, long lastTweetPostedId); + Task GetTwitterUserAsync(string acct); + Task GetAllTwitterUsersAsync(); + Task UpdateTwitterUserAsync(int id, long lastTweetPostedId, long lastTweetSynchronizedForAllFollowersId); + Task DeleteTwitterUserAsync(string acct); } } \ No newline at end of file diff --git a/src/Tests/BirdsiteLive.DAL.Postgres.Tests/DataAccessLayers/Base/PostgresTestingBase.cs b/src/Tests/BirdsiteLive.DAL.Postgres.Tests/DataAccessLayers/Base/PostgresTestingBase.cs new file mode 100644 index 0000000..72bf352 --- /dev/null +++ b/src/Tests/BirdsiteLive.DAL.Postgres.Tests/DataAccessLayers/Base/PostgresTestingBase.cs @@ -0,0 +1,27 @@ +using BirdsiteLive.DAL.Postgres.Settings; +using BirdsiteLive.DAL.Postgres.Tools; +using BirdsiteLive.DAL.Tools; + +namespace BirdsiteLive.DAL.Postgres.Tests.DataAccessLayers.Base +{ + public class PostgresTestingBase + { + protected readonly PostgresSettings _settings; + protected readonly PostgresTools _tools; + + #region Ctor + public PostgresTestingBase() + { + _settings = new PostgresSettings + { + ConnString = "Host=127.0.0.1;Username=postgres;Password=mysecretpassword;Database=mytestdb", + DbVersionTableName = "DbVersionTableName" + RandomGenerator.GetString(4), + CachedTweetsTableName = "CachedTweetsTableName" + RandomGenerator.GetString(4), + FollowersTableName = "FollowersTableName" + RandomGenerator.GetString(4), + TwitterUserTableName = "TwitterUserTableName" + RandomGenerator.GetString(4), + }; + _tools = new PostgresTools(_settings); + } + #endregion + } +} \ No newline at end of file diff --git a/src/Tests/BirdsiteLive.DAL.Postgres.Tests/DataAccessLayers/DbInitializerPostgresDalTests.cs b/src/Tests/BirdsiteLive.DAL.Postgres.Tests/DataAccessLayers/DbInitializerPostgresDalTests.cs index 5ca5968..7fc5383 100644 --- a/src/Tests/BirdsiteLive.DAL.Postgres.Tests/DataAccessLayers/DbInitializerPostgresDalTests.cs +++ b/src/Tests/BirdsiteLive.DAL.Postgres.Tests/DataAccessLayers/DbInitializerPostgresDalTests.cs @@ -1,34 +1,14 @@ using System; using System.Threading.Tasks; using BirdsiteLive.DAL.Postgres.DataAccessLayers; -using BirdsiteLive.DAL.Postgres.Settings; -using BirdsiteLive.DAL.Postgres.Tools; -using BirdsiteLive.DAL.Tools; +using BirdsiteLive.DAL.Postgres.Tests.DataAccessLayers.Base; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace BirdsiteLive.DAL.Postgres.Tests.DataAccessLayers { [TestClass] - public class DbInitializerPostgresDalTests + public class DbInitializerPostgresDalTests : PostgresTestingBase { - private readonly PostgresSettings _settings; - private readonly PostgresTools _tools; - - #region Ctor - public DbInitializerPostgresDalTests() - { - _settings = new PostgresSettings - { - ConnString = "Host=127.0.0.1;Username=postgres;Password=mysecretpassword;Database=mytestdb", - DbVersionTableName = "DbVersionTableName" + RandomGenerator.GetString(4), - CachedTweetsTableName = "CachedTweetsTableName" + RandomGenerator.GetString(4), - FollowersTableName = "FollowersTableName" + RandomGenerator.GetString(4), - TwitterUserTableName = "TwitterUserTableName" + RandomGenerator.GetString(4), - }; - _tools = new PostgresTools(_settings); - } - #endregion - [TestCleanup] public async Task CleanUp() { diff --git a/src/Tests/BirdsiteLive.DAL.Postgres.Tests/DataAccessLayers/TwitterUserPostgresDalTests.cs b/src/Tests/BirdsiteLive.DAL.Postgres.Tests/DataAccessLayers/TwitterUserPostgresDalTests.cs new file mode 100644 index 0000000..266a023 --- /dev/null +++ b/src/Tests/BirdsiteLive.DAL.Postgres.Tests/DataAccessLayers/TwitterUserPostgresDalTests.cs @@ -0,0 +1,99 @@ +using System; +using System.Threading.Tasks; +using System.Xml; +using BirdsiteLive.DAL.Postgres.DataAccessLayers; +using BirdsiteLive.DAL.Postgres.Tests.DataAccessLayers.Base; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace BirdsiteLive.DAL.Postgres.Tests.DataAccessLayers +{ + [TestClass] + public class TwitterUserPostgresDalTests : PostgresTestingBase + { + [TestInitialize] + public async Task TestInit() + { + var dal = new DbInitializerPostgresDal(_settings, _tools); + await dal.InitDbAsync(); + } + + [TestCleanup] + public async Task CleanUp() + { + var dal = new DbInitializerPostgresDal(_settings, _tools); + try + { + await dal.DeleteAllAsync(); + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + + [TestMethod] + public async Task GetTwitterUserAsync_NoUser() + { + var dal = new TwitterUserPostgresDal(_settings); + var result = await dal.GetTwitterUserAsync("dontexist"); + Assert.IsNull(result); + } + + [TestMethod] + public async Task CreateAndGetUser() + { + var acct = "myid"; + var lastTweetId = 1548L; + + var dal = new TwitterUserPostgresDal(_settings); + + await dal.CreateTwitterUserAsync(acct, lastTweetId); + var result = await dal.GetTwitterUserAsync(acct); + + Assert.AreEqual(acct, result.Acct); + Assert.AreEqual(lastTweetId, result.LastTweetPostedId); + Assert.AreEqual(lastTweetId, result.LastTweetSynchronizedForAllFollowersId); + Assert.IsTrue(result.Id > 0); + } + + [TestMethod] + public async Task CreateUpdateAndGetUser() + { + var acct = "myid"; + var lastTweetId = 1548L; + + var dal = new TwitterUserPostgresDal(_settings); + + await dal.CreateTwitterUserAsync(acct, lastTweetId); + var result = await dal.GetTwitterUserAsync(acct); + + + var updatedLastTweetId = 1600L; + var updatedLastSyncId = 1550L; + await dal.UpdateTwitterUserAsync(result.Id, updatedLastTweetId, updatedLastSyncId); + + result = await dal.GetTwitterUserAsync(acct); + + Assert.AreEqual(acct, result.Acct); + Assert.AreEqual(updatedLastTweetId, result.LastTweetPostedId); + Assert.AreEqual(updatedLastSyncId, result.LastTweetSynchronizedForAllFollowersId); + } + + [TestMethod] + public async Task CreateAndDeleteUser() + { + var acct = "myid"; + var lastTweetId = 1548L; + + var dal = new TwitterUserPostgresDal(_settings); + + await dal.CreateTwitterUserAsync(acct, lastTweetId); + var result = await dal.GetTwitterUserAsync(acct); + Assert.IsNotNull(result); + + await dal.DeleteTwitterUserAsync(acct); + result = await dal.GetTwitterUserAsync(acct); + Assert.IsNull(result); + } + } +} \ No newline at end of file