From d60924049d37768cb504b0bd3f32701b8338d7c1 Mon Sep 17 00:00:00 2001 From: Chris Kaczor Date: Sun, 28 Jul 2019 09:50:43 -0400 Subject: [PATCH] Switch to SQL Server --- Weather/Service/Data/Database.cs | 30 ++++++------- .../Service/Data/Resources/CreateReading.sql | 11 +++-- Weather/Service/Data/Resources/Schema.sql | 45 +++++++++---------- Weather/Service/MessageHandler.cs | 8 +++- Weather/Service/Service.csproj | 4 +- Weather/Service/appsettings.json | 2 +- Weather/Service/deploy/manifest.yaml | 25 +++++------ 7 files changed, 62 insertions(+), 63 deletions(-) diff --git a/Weather/Service/Data/Database.cs b/Weather/Service/Data/Database.cs index a555ddd..39deee5 100644 --- a/Weather/Service/Data/Database.cs +++ b/Weather/Service/Data/Database.cs @@ -1,7 +1,7 @@ using ChrisKaczor.HomeMonitor.Weather.Models; using Dapper; using Microsoft.Extensions.Configuration; -using Npgsql; +using System.Data.SqlClient; namespace ChrisKaczor.HomeMonitor.Weather.Service.Data { @@ -16,22 +16,22 @@ namespace ChrisKaczor.HomeMonitor.Weather.Service.Data public void EnsureDatabase() { - var connectionStringBuilder = new NpgsqlConnectionStringBuilder + var connectionStringBuilder = new SqlConnectionStringBuilder { - Host = _configuration["Weather:Database:Host"], - Username = _configuration["Weather:Database:User"], + DataSource = _configuration["Weather:Database:Host"], + UserID = _configuration["Weather:Database:User"], Password = _configuration["Weather:Database:Password"], - Database = "postgres" + InitialCatalog = "master" }; - using (var connection = new NpgsqlConnection(connectionStringBuilder.ConnectionString)) + using (var connection = new SqlConnection(connectionStringBuilder.ConnectionString)) { - var command = new NpgsqlCommand { Connection = connection }; + var command = new SqlCommand { Connection = connection }; connection.Open(); // Check to see if the database exists - command.CommandText = $"SELECT TRUE from pg_database WHERE datname='{_configuration["Weather:Database:Name"]}'"; + command.CommandText = $"SELECT CAST(1 as bit) from sys.databases WHERE name='{_configuration["Weather:Database:Name"]}'"; var databaseExists = (bool?)command.ExecuteScalar(); // Create database if needed @@ -52,17 +52,17 @@ namespace ChrisKaczor.HomeMonitor.Weather.Service.Data } } - private NpgsqlConnection CreateConnection() + private SqlConnection CreateConnection() { - var connectionStringBuilder = new NpgsqlConnectionStringBuilder + var connectionStringBuilder = new SqlConnectionStringBuilder { - Host = _configuration["Weather:Database:Host"], - Username = _configuration["Weather:Database:User"], + DataSource = _configuration["Weather:Database:Host"], + UserID = _configuration["Weather:Database:User"], Password = _configuration["Weather:Database:Password"], - Database = _configuration["Weather:Database:Name"] + InitialCatalog = _configuration["Weather:Database:Name"] }; - var connection = new NpgsqlConnection(connectionStringBuilder.ConnectionString); + var connection = new SqlConnection(connectionStringBuilder.ConnectionString); connection.Open(); return connection; @@ -74,7 +74,7 @@ namespace ChrisKaczor.HomeMonitor.Weather.Service.Data { var query = ResourceReader.GetString("ChrisKaczor.HomeMonitor.Weather.Service.Data.Resources.CreateReading.sql"); - connection.Execute(query, weatherMessage); + connection.Query(query, weatherMessage); } } } diff --git a/Weather/Service/Data/Resources/CreateReading.sql b/Weather/Service/Data/Resources/CreateReading.sql index 18ef1b1..9b24f53 100644 --- a/Weather/Service/Data/Resources/CreateReading.sql +++ b/Weather/Service/Data/Resources/CreateReading.sql @@ -1,6 +1,5 @@ -INSERT INTO weather_reading (timestamp, wind_direction, wind_speed, humidity, humidity_temperature, rain, pressure, - pressure_temperature, battery_level, light_level, latitude, longitude, altitude, - satellite_count, gps_timestamp) -VALUES (:timestamp, :windDirection, :windSpeed, :humidity, :humidityTemperature, :rain, :pressure, :pressureTemperature, - :batteryLevel, :lightLevel, :latitude, :longitude, :altitude, :satelliteCount, :gpsTimestamp) -ON CONFLICT DO NOTHING \ No newline at end of file +INSERT INTO Reading (Timestamp, WindDirection, WindSpeed, Humidity, HumidityTemperature, Rain, Pressure, + PressureTemperature, BatteryLevel, LightLevel, Latitude, Longitude, Altitude, + SatelliteCount, GpsTimestamp) +VALUES (@Timestamp, @WindDirection, @WindSpeed, @Humidity, @HumidityTemperature, @Rain, @Pressure, @PressureTemperature, + @BatteryLevel, @LightLevel, @Latitude, @Longitude, @Altitude, @SatelliteCount, @GpsTimestamp) \ No newline at end of file diff --git a/Weather/Service/Data/Resources/Schema.sql b/Weather/Service/Data/Resources/Schema.sql index 85a76ca..4a12626 100644 --- a/Weather/Service/Data/Resources/Schema.sql +++ b/Weather/Service/Data/Resources/Schema.sql @@ -1,24 +1,21 @@ -CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE; - -CREATE TABLE IF NOT EXISTS weather_reading -( - timestamp timestamptz NOT NULL - CONSTRAINT weather_reading_pk - PRIMARY KEY, - wind_direction int NOT NULL, - wind_speed double precision NOT NULL, - humidity double precision NOT NULL, - humidity_temperature double precision NOT NULL, - rain double precision NOT NULL, - pressure double precision NOT NULL, - pressure_temperature double precision NOT NULL, - battery_level double precision NOT NULL, - light_level double precision NOT NULL, - latitude double precision NOT NULL, - longitude double precision NOT NULL, - altitude double precision NOT NULL, - satellite_count double precision NOT NULL, - gps_timestamp timestamptz NOT NULL -); - -SELECT create_hypertable('weather_reading', 'timestamp', if_not_exists => TRUE); \ No newline at end of file +IF NOT EXISTS(SELECT 1 FROM sys.tables WHERE name = 'Reading') + CREATE TABLE Reading + ( + Timestamp datetimeoffset NOT NULL + CONSTRAINT reading_pk + PRIMARY KEY, + WindDirection int NOT NULL, + WindSpeed decimal(4, 1) NOT NULL, + Humidity decimal(4, 1) NOT NULL, + HumidityTemperature decimal(4, 1) NOT NULL, + Rain decimal(2, 2) NOT NULL, + Pressure decimal(8, 2) NOT NULL, + PressureTemperature decimal(4, 1) NOT NULL, + BatteryLevel decimal(3, 2) NOT NULL, + LightLevel decimal(3, 2) NOT NULL, + Latitude decimal(9, 6) NOT NULL, + Longitude decimal(9, 6) NOT NULL, + Altitude decimal(5, 1) NOT NULL, + SatelliteCount int NOT NULL, + GpsTimestamp datetimeoffset NOT NULL + ); diff --git a/Weather/Service/MessageHandler.cs b/Weather/Service/MessageHandler.cs index b23b227..ba57a05 100644 --- a/Weather/Service/MessageHandler.cs +++ b/Weather/Service/MessageHandler.cs @@ -55,7 +55,8 @@ namespace ChrisKaczor.HomeMonitor.Weather.Service _queueModel.BasicConsume(_configuration["Weather:Queue:Name"], true, consumer); - _hubConnection = new HubConnectionBuilder().WithUrl(_configuration["Hub:Weather"]).Build(); + if (!string.IsNullOrEmpty(_configuration["Hub:Weather"])) + _hubConnection = new HubConnectionBuilder().WithUrl(_configuration["Hub:Weather"]).Build(); return Task.CompletedTask; } @@ -64,7 +65,7 @@ namespace ChrisKaczor.HomeMonitor.Weather.Service { WriteLog("MessageHandler: Stop"); - _hubConnection.StopAsync(cancellationToken).Wait(cancellationToken); + _hubConnection?.StopAsync(cancellationToken).Wait(cancellationToken); _queueModel.Close(); _queueConnection.Close(); @@ -100,6 +101,9 @@ namespace ChrisKaczor.HomeMonitor.Weather.Service _database.StoreWeatherData(weatherMessage); + if (_hubConnection == null) + return; + try { if (_hubConnection.State == HubConnectionState.Disconnected) diff --git a/Weather/Service/Service.csproj b/Weather/Service/Service.csproj index d0ee260..fa95849 100644 --- a/Weather/Service/Service.csproj +++ b/Weather/Service/Service.csproj @@ -19,12 +19,12 @@ - + - + diff --git a/Weather/Service/appsettings.json b/Weather/Service/appsettings.json index 514246e..f6be04a 100644 --- a/Weather/Service/appsettings.json +++ b/Weather/Service/appsettings.json @@ -6,7 +6,7 @@ }, "Weather": { "Database": { - "Name": "weather" + "Name": "Weather" }, "Queue": { "Name": "weather" diff --git a/Weather/Service/deploy/manifest.yaml b/Weather/Service/deploy/manifest.yaml index 53ed6c5..9a12afb 100644 --- a/Weather/Service/deploy/manifest.yaml +++ b/Weather/Service/deploy/manifest.yaml @@ -19,26 +19,25 @@ spec: spec: containers: - name: weather-database - image: timescale/timescaledb + image: mcr.microsoft.com/mssql/server terminationMessagePath: "/dev/termination-log" terminationMessagePolicy: File imagePullPolicy: IfNotPresent env: - - name: POSTGRES_USER - valueFrom: - secretKeyRef: - name: weather-database-credentials - key: username - - name: POSTGRES_PASSWORD + - name: SA_PASSWORD valueFrom: secretKeyRef: name: weather-database-credentials key: password - - name: POSTGRES_DB - value: weather + - name: ACCEPT_EULA + value: "Y" + - name: MSSQL_PID + value: Express + - name: TZ + value: America/New_York volumeMounts: - name: data - mountPath: /var/lib/postgresql/data + mountPath: /var/opt/mssql restartPolicy: Always terminationGracePeriodSeconds: 30 dnsPolicy: ClusterFirst @@ -53,7 +52,7 @@ spec: storageClassName: local-path resources: requests: - storage: 4Gi + storage: 4Gi --- kind: Service apiVersion: v1 @@ -62,10 +61,10 @@ metadata: spec: ports: - name: client - port: 5432 + port: 1433 selector: app: weather-database - type: ClusterIP + type: LoadBalancer --- kind: Deployment apiVersion: apps/v1