From 199c7d70a93874ec2f6238d242773c46e8db095a Mon Sep 17 00:00:00 2001 From: Admir Trakic Date: Thu, 12 Dec 2024 20:36:50 +0100 Subject: [PATCH] Seed data --- .github/workflows/ci.yml | 8 +-- DbProject/dbo/Tables/DimCustomer.sql | 4 -- DbProject/dbo/Tables/DimDate.sql | 8 +-- DbProject/dbo/Tables/DimProduct.sql | 2 - .../dbo/Views/vSalesByCityAndCategory.sql | 17 +++++ DbProject/dbo/Views/vSalesByRegion.sql | 18 ----- SQL/dw-seed.sql | 47 +++++++++++++ azure-sql-deploy-dacpac.sln | 11 +++ compose.yml | 26 ++++++- src/SqlClient.ConsoleApp/.dockerignore | 8 +++ src/SqlClient.ConsoleApp/Dockerfile | 19 ++++++ src/SqlClient.ConsoleApp/Program.cs | 67 +++++++++++++++++++ .../SqlClient.ConsoleApp.csproj | 17 +++++ 13 files changed, 212 insertions(+), 40 deletions(-) create mode 100644 DbProject/dbo/Views/vSalesByCityAndCategory.sql delete mode 100644 DbProject/dbo/Views/vSalesByRegion.sql create mode 100644 SQL/dw-seed.sql create mode 100644 src/SqlClient.ConsoleApp/.dockerignore create mode 100644 src/SqlClient.ConsoleApp/Dockerfile create mode 100644 src/SqlClient.ConsoleApp/Program.cs create mode 100644 src/SqlClient.ConsoleApp/SqlClient.ConsoleApp.csproj diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b3eda75..8f06a02 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,10 +10,4 @@ jobs: steps: - uses: actions/checkout@v4 - name: Build the stack - run: docker compose up -d - - name: Test - run: docker compose logs sqlpackage - - name: Stats - run: docker compose stats --no-stream - - name: Stop the stack - run: docker compose down -v + run: docker compose up --quiet-pull --no-color --remove-orphans --abort-on-container-failure --exit-code-from seed diff --git a/DbProject/dbo/Tables/DimCustomer.sql b/DbProject/dbo/Tables/DimCustomer.sql index a1f344e..fc7bbe3 100644 --- a/DbProject/dbo/Tables/DimCustomer.sql +++ b/DbProject/dbo/Tables/DimCustomer.sql @@ -1,13 +1,9 @@ CREATE TABLE [dbo].[DimCustomer] ( [CustomerKey] INT NOT NULL PRIMARY KEY, - [CustomerAltKey] VARCHAR (50) NULL, - [Title] VARCHAR (5) NULL, [FirstName] VARCHAR (50) NOT NULL, [LastName] VARCHAR (50) NULL, [AddressLine1] VARCHAR (200) NULL, [City] VARCHAR (50) NULL, - [StateProvince] VARCHAR (50) NULL, - [CountryRegion] VARCHAR (50) NULL, [PostalCode] VARCHAR (20) NULL ); diff --git a/DbProject/dbo/Tables/DimDate.sql b/DbProject/dbo/Tables/DimDate.sql index 5941054..e877efa 100644 --- a/DbProject/dbo/Tables/DimDate.sql +++ b/DbProject/dbo/Tables/DimDate.sql @@ -1,12 +1,6 @@ CREATE TABLE [dbo].[DimDate] ( [DateKey] INT NOT NULL PRIMARY KEY, - [DateAltKey] DATE NOT NULL, - [DayOfWeek] INT NOT NULL, - [WeekDayName] VARCHAR (10) NULL, - [DayOfMonth] INT NOT NULL, - [Month] INT NOT NULL, - [MonthName] VARCHAR (12) NULL, - [Year] INT NOT NULL + [Date] DATE NOT NULL ); diff --git a/DbProject/dbo/Tables/DimProduct.sql b/DbProject/dbo/Tables/DimProduct.sql index c90815c..a190420 100644 --- a/DbProject/dbo/Tables/DimProduct.sql +++ b/DbProject/dbo/Tables/DimProduct.sql @@ -1,7 +1,5 @@ CREATE TABLE [dbo].[DimProduct] ( - -- Update comment [ProductKey] INT NOT NULL PRIMARY KEY, - [ProductAltKey] VARCHAR (25) NULL, [ProductName] VARCHAR (50) NOT NULL, [Category] VARCHAR (50) NULL, [ListPrice] DECIMAL (18) NULL diff --git a/DbProject/dbo/Views/vSalesByCityAndCategory.sql b/DbProject/dbo/Views/vSalesByCityAndCategory.sql new file mode 100644 index 0000000..da975a6 --- /dev/null +++ b/DbProject/dbo/Views/vSalesByCityAndCategory.sql @@ -0,0 +1,17 @@ + +CREATE VIEW vSalesByCityAndCategory +AS + SELECT + c.City, + p.Category, + SUM(f.Quantity) AS TotalQuantity, + SUM(f.SalesTotal) AS TotalSales + FROM + dbo.FactSalesOrder f + INNER JOIN dbo.DimCustomer c ON f.CustomerKey = c.CustomerKey + INNER JOIN dbo.DimProduct p ON f.ProductKey = p.ProductKey + GROUP BY + c.City, + p.Category + +GO diff --git a/DbProject/dbo/Views/vSalesByRegion.sql b/DbProject/dbo/Views/vSalesByRegion.sql deleted file mode 100644 index 54559e8..0000000 --- a/DbProject/dbo/Views/vSalesByRegion.sql +++ /dev/null @@ -1,18 +0,0 @@ - -CREATE VIEW vSalesByRegion -AS - SELECT d.[Year] AS CalendarYear, - d.[Month] AS MonthOfYear, - d.MonthName AS MonthName, - c.CountryRegion AS SalesRegion, - SUM(so.SalesTotal) AS SalesRevenue - FROM - FactSalesOrder AS so - JOIN - DimDate AS d ON so.SalesOrderDateKey = d.DateKey - JOIN - DimCustomer AS c ON so.CustomerKey = c.CustomerKey - GROUP BY - d.[Year], d.[Month], d.MonthName, c.CountryRegion; - -GO diff --git a/SQL/dw-seed.sql b/SQL/dw-seed.sql new file mode 100644 index 0000000..4eb119d --- /dev/null +++ b/SQL/dw-seed.sql @@ -0,0 +1,47 @@ +-- Insert sample data into the Customers table +MERGE INTO DimCustomer AS target +USING (VALUES + (1, 'John', 'Doe', '123 Main St', 'Springfield', '12345'), + (2, 'Jane', 'Smith', '456 Elm St', 'Springfield', '12345'), + (3, 'Bob', 'Jones', '789 Oak St', 'Springfield', '12345') +) AS source (CustomerKey, FirstName, LastName, AddressLine1, City, PostalCode) +ON target.CustomerKey = source.CustomerKey +WHEN NOT MATCHED BY TARGET THEN + INSERT (CustomerKey, FirstName, LastName, AddressLine1, City, PostalCode) + VALUES (source.CustomerKey, source.FirstName, source.LastName, source.AddressLine1, source.City, source.PostalCode); + +-- Insert sample data into the DimProducts table +MERGE INTO DimProduct AS target +USING (VALUES + (1, 'Bike', 'BK-001', 1000.00), + (2, 'Car', 'CR-001', 2000.00), + (3, 'Truck', 'TR-001', 3000.00) +) AS source (ProductKey, ProductName, Category, ListPrice) +ON target.ProductKey = source.ProductKey +WHEN NOT MATCHED BY TARGET THEN + INSERT (ProductKey, ProductName, Category, ListPrice) + VALUES (source.ProductKey, source.ProductName, source.Category, source.ListPrice); + +-- Insert sample data into the DimDate table +MERGE INTO DimDate AS target +USING (VALUES + (1, '2020-01-01'), + (2, '2020-01-02'), + (3, '2020-01-03') +) AS source (DateKey, Date) +ON target.DateKey = source.DateKey +WHEN NOT MATCHED BY TARGET THEN + INSERT (DateKey, Date) + VALUES (source.DateKey, source.Date); + +-- Insert sample data into the FactSales table +MERGE INTO FactSalesOrder AS target +USING (VALUES + (1, 1, 1, 1, 1, 1000.00), + (2, 2, 2, 2, 2, 4000.00), + (3, 3, 3, 3, 3, 9000.00) +) AS source (SalesOrderKey, SalesOrderDateKey, ProductKey, CustomerKey, Quantity, SalesTotal) +ON target.SalesOrderKey = source.SalesOrderKey +WHEN NOT MATCHED BY TARGET THEN + INSERT (SalesOrderKey, SalesOrderDateKey, ProductKey, CustomerKey, Quantity, SalesTotal) + VALUES (source.SalesOrderKey, source.SalesOrderDateKey, source.ProductKey, source.CustomerKey, source.Quantity, source.SalesTotal); diff --git a/azure-sql-deploy-dacpac.sln b/azure-sql-deploy-dacpac.sln index 53006fa..4523673 100644 --- a/azure-sql-deploy-dacpac.sln +++ b/azure-sql-deploy-dacpac.sln @@ -5,6 +5,10 @@ VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DbProject", "DbProject\DbProject.sqlproj", "{0DA6EF13-79FA-455F-85E0-C6A54842EED0}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A1AF7517-E017-4C34-A844-B6A2A78D141A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlClient.ConsoleApp", "src\SqlClient.ConsoleApp\SqlClient.ConsoleApp.csproj", "{405F855C-1D92-41FF-9E1A-EDDCE4305170}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -18,5 +22,12 @@ Global {0DA6EF13-79FA-455F-85E0-C6A54842EED0}.Debug|Any CPU.Build.0 = Debug|Any CPU {0DA6EF13-79FA-455F-85E0-C6A54842EED0}.Release|Any CPU.ActiveCfg = Release|Any CPU {0DA6EF13-79FA-455F-85E0-C6A54842EED0}.Release|Any CPU.Build.0 = Release|Any CPU + {405F855C-1D92-41FF-9E1A-EDDCE4305170}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {405F855C-1D92-41FF-9E1A-EDDCE4305170}.Debug|Any CPU.Build.0 = Debug|Any CPU + {405F855C-1D92-41FF-9E1A-EDDCE4305170}.Release|Any CPU.ActiveCfg = Release|Any CPU + {405F855C-1D92-41FF-9E1A-EDDCE4305170}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {405F855C-1D92-41FF-9E1A-EDDCE4305170} = {A1AF7517-E017-4C34-A844-B6A2A78D141A} EndGlobalSection EndGlobal diff --git a/compose.yml b/compose.yml index 7ac1ed6..92f90e1 100644 --- a/compose.yml +++ b/compose.yml @@ -1,4 +1,28 @@ services: + seed: + build: + context: ./src/SqlClient.ConsoleApp + tty: true + container_name: seed + working_dir: /app + env_file: + - .env + environment: + ConnectionString: "Server=tcp:db,1433;Initial Catalog=demo;UID=sa;Password=${MSSQL_SA_PASSWORD};TrustServerCertificate=true;Connection Timeout=3;" + volumes: + - $PWD/SQL/dw-seed.sql:/seed.sql + entrypoint: + - /bin/sh + - -c + - | + ./SqlClient.ConsoleApp /seed.sql + # keep the container running (for debugging) + #tail -f /dev/null + depends_on: + sqlpackage: + condition: service_completed_successfully + required: true + sqlpackage: build: context: ./docker/sqlpackage @@ -19,8 +43,6 @@ services: - -c - | /scripts/deploy.sh - # keep the container running (for debugging) - tail -f /dev/null depends_on: db: condition: service_healthy diff --git a/src/SqlClient.ConsoleApp/.dockerignore b/src/SqlClient.ConsoleApp/.dockerignore new file mode 100644 index 0000000..79326b9 --- /dev/null +++ b/src/SqlClient.ConsoleApp/.dockerignore @@ -0,0 +1,8 @@ +# directories +**/bin/ +**/obj/ +**/out/ + +# files +Dockerfile* +**/*.md diff --git a/src/SqlClient.ConsoleApp/Dockerfile b/src/SqlClient.ConsoleApp/Dockerfile new file mode 100644 index 0000000..ed1e174 --- /dev/null +++ b/src/SqlClient.ConsoleApp/Dockerfile @@ -0,0 +1,19 @@ +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:9.0 AS build +ARG TARGETARCH +WORKDIR /source + +# Copy the project file and restore dependencies +COPY *.csproj ./ +RUN dotnet restore -a $TARGETARCH + +# Copy source code and publish app +COPY . ./ +RUN dotnet publish -c Release -a $TARGETARCH --no-restore -o /app + +# Use the official Microsoft .NET runtime image +FROM mcr.microsoft.com/dotnet/runtime:9.0 AS final +WORKDIR /app +COPY --link --from=build /app ./ +ARG APP_UID=1000 +USER $APP_UID +ENTRYPOINT ["./SqlClient.ConsoleApp"] diff --git a/src/SqlClient.ConsoleApp/Program.cs b/src/SqlClient.ConsoleApp/Program.cs new file mode 100644 index 0000000..3396322 --- /dev/null +++ b/src/SqlClient.ConsoleApp/Program.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Diagnostics; +using Microsoft.Data.SqlClient; +using System.Threading.Tasks; +using static System.Console; + +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.DependencyInjection; + +namespace SqlClient.ConsoleApp +{ + class Program + { + static async Task Main(string[] args) + { + + var serviceProvider = new ServiceCollection() + .AddLogging(configure => configure.AddConsole()) + .BuildServiceProvider(); + + var logger = serviceProvider.GetService>(); + + + string connection = Environment.GetEnvironmentVariable("ConnectionString") + ?? throw new ArgumentException("Missing 'ConnectionString' env variable"); + + if (args.Length == 0) + { + logger.LogInformation("Please provide the path to the SQL file:"); + string filePath = ReadLine(); + if (string.IsNullOrEmpty(filePath)) + { + logger.LogError("Missing SQL file argument"); + throw new ArgumentException("Missing SQL file argument"); + } + args = new string[] { filePath }; + } + + try + { + string _sql = System.IO.File.ReadAllText(args[0]); + SqlConnection conn = new SqlConnection(connection); + conn.Open(); + + var logMessage = new + { + Message = "Connected to SQL Server: ", + ServerVersion = conn.ServerVersion, + OSVersion = Environment.OSVersion.VersionString + }; + logger.LogInformation(JsonSerializer.Serialize(logMessage)); + + SqlCommand cmd = new SqlCommand(_sql, conn); + var qr = await cmd.ExecuteScalarAsync(); + logger.LogInformation($"Query from file: {args[0]} executed successfully."); + logger.LogInformation($"Result: {qr}"); + conn.Close(); + } + catch (Exception ex) + { + logger.LogError(ex, "An error occurred while executing the SQL file."); + } + } + } +} diff --git a/src/SqlClient.ConsoleApp/SqlClient.ConsoleApp.csproj b/src/SqlClient.ConsoleApp/SqlClient.ConsoleApp.csproj new file mode 100644 index 0000000..d4b9276 --- /dev/null +++ b/src/SqlClient.ConsoleApp/SqlClient.ConsoleApp.csproj @@ -0,0 +1,17 @@ + + + + Exe + net9.0 + true + false + + + + + + + + + +