diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml
index c6b7818..645b026 100644
--- a/.github/workflows/dotnet-core.yml
+++ b/.github/workflows/dotnet-core.yml
@@ -15,6 +15,8 @@ jobs:
steps:
- uses: actions/checkout@v2
+ - name: Launch Db for testing
+ run: docker run --name postgres -e POSTGRES_DB=mytestdb -e POSTGRES_PASSWORD=mysecretpassword -d -p 5432:5432 postgres
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
diff --git a/src/BirdsiteLive.sln b/src/BirdsiteLive.sln
index 8e1b53b..d600aa6 100644
--- a/src/BirdsiteLive.sln
+++ b/src/BirdsiteLive.sln
@@ -17,11 +17,19 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{A32D3458
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BirdsiteLive.Cryptography.Tests", "Tests\BirdsiteLive.Cryptography.Tests\BirdsiteLive.Cryptography.Tests.csproj", "{155D46A4-2D05-47F2-8FFC-0B7C412A7652}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BirdsiteLive.Domain", "BirdsiteLive.Domain\BirdsiteLive.Domain.csproj", "{D48450EE-D8BD-4228-9864-043AC88F7EE0}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BirdsiteLive.Domain", "BirdsiteLive.Domain\BirdsiteLive.Domain.csproj", "{D48450EE-D8BD-4228-9864-043AC88F7EE0}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BirdsiteLive.ActivityPub", "BirdsiteLive.ActivityPub\BirdsiteLive.ActivityPub.csproj", "{7463E1E2-9736-4A46-8507-010BDD8ECFBB}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BirdsiteLive.ActivityPub", "BirdsiteLive.ActivityPub\BirdsiteLive.ActivityPub.csproj", "{7463E1E2-9736-4A46-8507-010BDD8ECFBB}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BirdsiteLive.ActivityPub.Tests", "Tests\BirdsiteLive.ActivityPub.Tests\BirdsiteLive.ActivityPub.Tests.csproj", "{1D713961-9926-41FF-8D6A-8A4B8D548484}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BirdsiteLive.ActivityPub.Tests", "Tests\BirdsiteLive.ActivityPub.Tests\BirdsiteLive.ActivityPub.Tests.csproj", "{1D713961-9926-41FF-8D6A-8A4B8D548484}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DataAccessLayers", "DataAccessLayers", "{CFAB3509-3931-42DB-AC97-4F91FC2D849C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BirdsiteLive.DAL", "DataAccessLayers\BirdsiteLive.DAL\BirdsiteLive.DAL.csproj", "{47058CAB-DC43-4DD1-8F68-D3D625332905}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BirdsiteLive.DAL.Postgres", "DataAccessLayers\BirdsiteLive.DAL.Postgres\BirdsiteLive.DAL.Postgres.csproj", "{87E46519-BBF2-437C-8A5B-CF6CDE7CDAA6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BirdsiteLive.DAL.Postgres.Tests", "Tests\BirdsiteLive.DAL.Postgres.Tests\BirdsiteLive.DAL.Postgres.Tests.csproj", "{CD9489BF-69C8-4705-8774-81C45F4F8FE1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -61,6 +69,18 @@ Global
{1D713961-9926-41FF-8D6A-8A4B8D548484}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1D713961-9926-41FF-8D6A-8A4B8D548484}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1D713961-9926-41FF-8D6A-8A4B8D548484}.Release|Any CPU.Build.0 = Release|Any CPU
+ {47058CAB-DC43-4DD1-8F68-D3D625332905}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {47058CAB-DC43-4DD1-8F68-D3D625332905}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {47058CAB-DC43-4DD1-8F68-D3D625332905}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {47058CAB-DC43-4DD1-8F68-D3D625332905}.Release|Any CPU.Build.0 = Release|Any CPU
+ {87E46519-BBF2-437C-8A5B-CF6CDE7CDAA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {87E46519-BBF2-437C-8A5B-CF6CDE7CDAA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {87E46519-BBF2-437C-8A5B-CF6CDE7CDAA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {87E46519-BBF2-437C-8A5B-CF6CDE7CDAA6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CD9489BF-69C8-4705-8774-81C45F4F8FE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CD9489BF-69C8-4705-8774-81C45F4F8FE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CD9489BF-69C8-4705-8774-81C45F4F8FE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CD9489BF-69C8-4705-8774-81C45F4F8FE1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -73,6 +93,9 @@ Global
{D48450EE-D8BD-4228-9864-043AC88F7EE0} = {4FEAD6BC-3C8E-451A-8CA1-FF1AF47D26CC}
{7463E1E2-9736-4A46-8507-010BDD8ECFBB} = {4FEAD6BC-3C8E-451A-8CA1-FF1AF47D26CC}
{1D713961-9926-41FF-8D6A-8A4B8D548484} = {A32D3458-09D0-4E0A-BA4B-8C411B816B94}
+ {47058CAB-DC43-4DD1-8F68-D3D625332905} = {CFAB3509-3931-42DB-AC97-4F91FC2D849C}
+ {87E46519-BBF2-437C-8A5B-CF6CDE7CDAA6} = {CFAB3509-3931-42DB-AC97-4F91FC2D849C}
+ {CD9489BF-69C8-4705-8774-81C45F4F8FE1} = {A32D3458-09D0-4E0A-BA4B-8C411B816B94}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {69E8DCAD-4C37-4010-858F-5F94E6FBABCE}
diff --git a/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/BirdsiteLive.DAL.Postgres.csproj b/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/BirdsiteLive.DAL.Postgres.csproj
new file mode 100644
index 0000000..690c878
--- /dev/null
+++ b/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/BirdsiteLive.DAL.Postgres.csproj
@@ -0,0 +1,16 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/DataAccessLayers/Base/PostgresBase.cs b/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/DataAccessLayers/Base/PostgresBase.cs
new file mode 100644
index 0000000..1c59387
--- /dev/null
+++ b/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/DataAccessLayers/Base/PostgresBase.cs
@@ -0,0 +1,25 @@
+using BirdsiteLive.DAL.Postgres.Settings;
+using Npgsql;
+
+namespace BirdsiteLive.DAL.Postgres.DataAccessLayers.Base
+{
+ public class PostgresBase
+ {
+ protected readonly PostgresSettings _settings;
+
+ #region Ctor
+ protected PostgresBase(PostgresSettings settings)
+ {
+ _settings = settings;
+ }
+ #endregion
+
+ protected NpgsqlConnection Connection
+ {
+ get
+ {
+ return new NpgsqlConnection(_settings.ConnString);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/DataAccessLayers/DbInitializerPostgresDal.cs b/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/DataAccessLayers/DbInitializerPostgresDal.cs
new file mode 100644
index 0000000..cbe37d5
--- /dev/null
+++ b/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/DataAccessLayers/DbInitializerPostgresDal.cs
@@ -0,0 +1,150 @@
+using System;
+using System.Data;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
+using System.Xml;
+using BirdsiteLive.DAL.Contracts;
+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
+{
+ internal class DbVersion
+ {
+ public string Type { get; set; }
+ public int Major { get; set; }
+ public int Minor { get; set; }
+ }
+
+ public class DbInitializerPostgresDal : PostgresBase, IDbInitializerDal
+ {
+ private readonly PostgresTools _tools;
+ private readonly Version _currentVersion = new Version(1,0);
+ private const string DbVersionType = "db-version";
+
+ #region Ctor
+ public DbInitializerPostgresDal(PostgresSettings settings, PostgresTools tools) : base(settings)
+ {
+ _tools = tools;
+ }
+ #endregion
+
+ public async Task GetCurrentDbVersionAsync()
+ {
+ var query = $"SELECT * FROM {_settings.DbVersionTableName} WHERE type = @type";
+
+ try
+ {
+ using (var dbConnection = Connection)
+ {
+ dbConnection.Open();
+
+ var result = (await dbConnection.QueryAsync(query, new { type = DbVersionType })).FirstOrDefault();
+
+ if (result == default)
+ return null;
+
+ return new Version(result.Major, result.Minor);
+ }
+ }
+ catch (PostgresException e)
+ {
+ if (e.Message.Contains("42P01"))
+ return null;
+
+ throw;
+ }
+ }
+
+ public Version GetMandatoryDbVersion()
+ {
+ return _currentVersion;
+ }
+
+ public Tuple[] GetMigrationPatterns()
+ {
+ return new Tuple[0];
+ }
+
+ public Task MigrateDbAsync(Version from, Version to)
+ {
+ throw new NotImplementedException();
+ }
+
+ public async Task InitDbAsync()
+ {
+ // Create version table
+ var createVersion = $@"CREATE TABLE {_settings.DbVersionTableName}
+ (
+ type VARCHAR(128) PRIMARY KEY,
+
+ major SMALLINT NOT NULL,
+ minor SMALLINT NOT NULL
+ );";
+ await _tools.ExecuteRequestAsync(createVersion);
+
+ // Create Twitter User table
+ var createTwitter = $@"CREATE TABLE {_settings.TwitterUserTableName}
+ (
+ id SERIAL PRIMARY KEY,
+ acct VARCHAR(20) UNIQUE,
+
+ lastTweetPostedId BIGINT,
+ lastTweetSynchronizedForAllFollowersId BIGINT
+ );";
+ await _tools.ExecuteRequestAsync(createTwitter);
+
+ // Create Followers table
+ var createFollowers = $@"CREATE TABLE {_settings.FollowersTableName}
+ (
+ id SERIAL PRIMARY KEY,
+
+ followings INTEGER[],
+ followingsSyncStatus JSONB,
+
+ acct VARCHAR(20) UNIQUE,
+ host VARCHAR(20)
+ );";
+ await _tools.ExecuteRequestAsync(createFollowers);
+
+ // Create Cached Tweet table
+ var createCachedTweets = $@"CREATE TABLE {_settings.CachedTweetsTableName}
+ (
+ id BIGINT PRIMARY KEY,
+ twitterUserId INTEGER,
+ data JSONB
+ );";
+ await _tools.ExecuteRequestAsync(createCachedTweets);
+
+ // Insert version to db
+ using (var dbConnection = Connection)
+ {
+ dbConnection.Open();
+
+ await dbConnection.ExecuteAsync(
+ $"INSERT INTO {_settings.DbVersionTableName} (type,major,minor) VALUES(@type,@major,@minor)",
+ new { type = DbVersionType, major = _currentVersion.Major, minor = _currentVersion.Minor });
+ }
+ }
+
+ public async Task DeleteAllAsync()
+ {
+ var dropsRequests = new[]
+ {
+ $@"DROP TABLE {_settings.DbVersionTableName};",
+ $@"DROP TABLE {_settings.TwitterUserTableName};",
+ $@"DROP TABLE {_settings.FollowersTableName};",
+ $@"DROP TABLE {_settings.CachedTweetsTableName};"
+ };
+
+ foreach (var r in dropsRequests)
+ {
+ await _tools.ExecuteRequestAsync(r);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/DataAccessLayers/FollowersPostgresDal.cs b/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/DataAccessLayers/FollowersPostgresDal.cs
new file mode 100644
index 0000000..ace1997
--- /dev/null
+++ b/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/DataAccessLayers/FollowersPostgresDal.cs
@@ -0,0 +1,9 @@
+using BirdsiteLive.DAL.Contracts;
+
+namespace BirdsiteLive.DAL.Postgres.DataAccessLayers
+{
+ public class FollowersPostgresDal : IFollowersDal
+ {
+
+ }
+}
\ 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
new file mode 100644
index 0000000..2058bf3
--- /dev/null
+++ b/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/DataAccessLayers/TwitterUserPostgresDal.cs
@@ -0,0 +1,9 @@
+using BirdsiteLive.DAL.Contracts;
+
+namespace BirdsiteLive.DAL.Postgres.DataAccessLayers
+{
+ public class TwitterUserPostgresDal : ITwitterUserDal
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/Settings/PostgresSettings.cs b/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/Settings/PostgresSettings.cs
new file mode 100644
index 0000000..8037a42
--- /dev/null
+++ b/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/Settings/PostgresSettings.cs
@@ -0,0 +1,12 @@
+namespace BirdsiteLive.DAL.Postgres.Settings
+{
+ public class PostgresSettings
+ {
+ public string ConnString { get; set; }
+
+ public string DbVersionTableName { get; set; } = "db-version";
+ public string TwitterUserTableName { get; set; } = "twitter-users";
+ public string FollowersTableName { get; set; } = "followers";
+ public string CachedTweetsTableName { get; set; } = "cached-tweets";
+ }
+}
\ No newline at end of file
diff --git a/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/Tools/PostgresTools.cs b/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/Tools/PostgresTools.cs
new file mode 100644
index 0000000..223b1ea
--- /dev/null
+++ b/src/DataAccessLayers/BirdsiteLive.DAL.Postgres/Tools/PostgresTools.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Threading.Tasks;
+using BirdsiteLive.DAL.Postgres.Settings;
+using Npgsql;
+
+namespace BirdsiteLive.DAL.Postgres.Tools
+{
+ public class PostgresTools
+ {
+ private readonly PostgresSettings _settings;
+
+ #region Ctor
+ public PostgresTools(PostgresSettings settings)
+ {
+ _settings = settings;
+ }
+ #endregion
+
+ public async Task ExecuteRequestAsync(string request)
+ {
+ try
+ {
+ using (var conn = new NpgsqlConnection(_settings.ConnString))
+ using (var cmd = new NpgsqlCommand(request, conn))
+ {
+ await conn.OpenAsync();
+ await cmd.ExecuteNonQueryAsync();
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/DataAccessLayers/BirdsiteLive.DAL/BirdsiteLive.DAL.csproj b/src/DataAccessLayers/BirdsiteLive.DAL/BirdsiteLive.DAL.csproj
new file mode 100644
index 0000000..9f5c4f4
--- /dev/null
+++ b/src/DataAccessLayers/BirdsiteLive.DAL/BirdsiteLive.DAL.csproj
@@ -0,0 +1,7 @@
+
+
+
+ netstandard2.0
+
+
+
diff --git a/src/DataAccessLayers/BirdsiteLive.DAL/Contracts/IDbInitializerDal.cs b/src/DataAccessLayers/BirdsiteLive.DAL/Contracts/IDbInitializerDal.cs
new file mode 100644
index 0000000..b786386
--- /dev/null
+++ b/src/DataAccessLayers/BirdsiteLive.DAL/Contracts/IDbInitializerDal.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Reflection;
+using System.Threading.Tasks;
+
+namespace BirdsiteLive.DAL.Contracts
+{
+ public interface IDbInitializerDal
+ {
+ Task GetCurrentDbVersionAsync();
+ Version GetMandatoryDbVersion();
+ Tuple[] GetMigrationPatterns();
+ Task MigrateDbAsync(Version from, Version to);
+ Task InitDbAsync();
+ }
+}
\ No newline at end of file
diff --git a/src/DataAccessLayers/BirdsiteLive.DAL/Contracts/IFollowersDal.cs b/src/DataAccessLayers/BirdsiteLive.DAL/Contracts/IFollowersDal.cs
new file mode 100644
index 0000000..ab8392d
--- /dev/null
+++ b/src/DataAccessLayers/BirdsiteLive.DAL/Contracts/IFollowersDal.cs
@@ -0,0 +1,7 @@
+namespace BirdsiteLive.DAL.Contracts
+{
+ public interface IFollowersDal
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/DataAccessLayers/BirdsiteLive.DAL/Contracts/ITwitterUserDal.cs b/src/DataAccessLayers/BirdsiteLive.DAL/Contracts/ITwitterUserDal.cs
new file mode 100644
index 0000000..195b49b
--- /dev/null
+++ b/src/DataAccessLayers/BirdsiteLive.DAL/Contracts/ITwitterUserDal.cs
@@ -0,0 +1,7 @@
+namespace BirdsiteLive.DAL.Contracts
+{
+ public interface ITwitterUserDal
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/DataAccessLayers/BirdsiteLive.DAL/Models/CachedTweet.cs b/src/DataAccessLayers/BirdsiteLive.DAL/Models/CachedTweet.cs
new file mode 100644
index 0000000..d1472b6
--- /dev/null
+++ b/src/DataAccessLayers/BirdsiteLive.DAL/Models/CachedTweet.cs
@@ -0,0 +1,10 @@
+namespace BirdsiteLive.DAL.Models
+{
+ public class CachedTweet
+ {
+ public long Id { get; set; }
+ public long TwitterUserId { get; set; }
+
+ public string TweetData { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/DataAccessLayers/BirdsiteLive.DAL/Models/Follower.cs b/src/DataAccessLayers/BirdsiteLive.DAL/Models/Follower.cs
new file mode 100644
index 0000000..a6c0903
--- /dev/null
+++ b/src/DataAccessLayers/BirdsiteLive.DAL/Models/Follower.cs
@@ -0,0 +1,13 @@
+namespace BirdsiteLive.DAL.Models
+{
+ public class Follower
+ {
+ public int Id { get; set; }
+ public int FollowingAccountId { get; set; }
+
+ public string Acct { get; set; }
+ public string Host { get; set; }
+
+ public long LastTweetSynchronizedId { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/DataAccessLayers/BirdsiteLive.DAL/Models/SyncTwitterUser.cs b/src/DataAccessLayers/BirdsiteLive.DAL/Models/SyncTwitterUser.cs
new file mode 100644
index 0000000..8061fc8
--- /dev/null
+++ b/src/DataAccessLayers/BirdsiteLive.DAL/Models/SyncTwitterUser.cs
@@ -0,0 +1,11 @@
+namespace BirdsiteLive.DAL.Models
+{
+ public class SyncTwitterUser
+ {
+ public int Id { get; set; }
+ public string Acct { get; set; }
+
+ public long LastTweetPostedId { get; set; }
+ public long LastTweetSynchronizedForAllFollowersId { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/DataAccessLayers/BirdsiteLive.DAL/Tools/RandomGenerator.cs b/src/DataAccessLayers/BirdsiteLive.DAL/Tools/RandomGenerator.cs
new file mode 100644
index 0000000..fabbb5e
--- /dev/null
+++ b/src/DataAccessLayers/BirdsiteLive.DAL/Tools/RandomGenerator.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Linq;
+
+namespace BirdsiteLive.DAL.Tools
+{
+ public static class RandomGenerator
+ {
+ private static readonly Random Random = new Random();
+
+ public static string GetString(int length)
+ {
+ const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ return new string(Enumerable.Repeat(chars, length)
+ .Select(s => s[Random.Next(s.Length)]).ToArray());
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/Tests/BirdsiteLive.DAL.Postgres.Tests/BirdsiteLive.DAL.Postgres.Tests.csproj b/src/Tests/BirdsiteLive.DAL.Postgres.Tests/BirdsiteLive.DAL.Postgres.Tests.csproj
new file mode 100644
index 0000000..da05ef2
--- /dev/null
+++ b/src/Tests/BirdsiteLive.DAL.Postgres.Tests/BirdsiteLive.DAL.Postgres.Tests.csproj
@@ -0,0 +1,20 @@
+
+
+
+ netcoreapp3.1
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Tests/BirdsiteLive.DAL.Postgres.Tests/DataAccessLayers/DbInitializerPostgresDalTests.cs b/src/Tests/BirdsiteLive.DAL.Postgres.Tests/DataAccessLayers/DbInitializerPostgresDalTests.cs
new file mode 100644
index 0000000..5ca5968
--- /dev/null
+++ b/src/Tests/BirdsiteLive.DAL.Postgres.Tests/DataAccessLayers/DbInitializerPostgresDalTests.cs
@@ -0,0 +1,68 @@
+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 Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace BirdsiteLive.DAL.Postgres.Tests.DataAccessLayers
+{
+ [TestClass]
+ public class DbInitializerPostgresDalTests
+ {
+ 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()
+ {
+ var dal = new DbInitializerPostgresDal(_settings, _tools);
+ try
+ {
+ await dal.DeleteAllAsync();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+ }
+
+ [TestMethod]
+ public async Task GetCurrentDbVersionAsync_UninitializedDb()
+ {
+ var dal = new DbInitializerPostgresDal(_settings, _tools);
+
+ var current = await dal.GetCurrentDbVersionAsync();
+ Assert.IsNull(current);
+ }
+
+ [TestMethod]
+ public async Task InitDbAsync()
+ {
+ var dal = new DbInitializerPostgresDal(_settings, _tools);
+
+ await dal.InitDbAsync();
+ var current = await dal.GetCurrentDbVersionAsync();
+ var mandatory = dal.GetMandatoryDbVersion();
+ Assert.IsNotNull(current);
+ Assert.AreEqual(mandatory.Minor, current.Minor);
+ Assert.AreEqual(mandatory.Major, current.Major);
+ }
+ }
+}
\ No newline at end of file