Update Environment to TimescaleDB

This commit is contained in:
2024-01-31 21:03:11 -05:00
parent 0fa45d13ae
commit f2c585c9d7
7 changed files with 100 additions and 72 deletions

View File

@@ -1,7 +1,7 @@
using System.Reflection;
using Dapper;
using Dapper;
using DbUp;
using Microsoft.Data.SqlClient;
using Npgsql;
using System.Reflection;
namespace ChrisKaczor.HomeMonitor.Environment.Service.Data;
@@ -9,12 +9,13 @@ public class Database(IConfiguration configuration)
{
private string GetConnectionString()
{
var connectionStringBuilder = new SqlConnectionStringBuilder
var connectionStringBuilder = new NpgsqlConnectionStringBuilder
{
DataSource = $"{configuration["Environment:Database:Host"]},{configuration["Environment:Database:Port"]}",
UserID = configuration["Environment:Database:User"],
Host = configuration["Environment:Database:Host"],
Port = configuration.GetValue<int>("Environment:Database:Port"),
Username = configuration["Environment:Database:User"],
Password = configuration["Environment:Database:Password"],
InitialCatalog = configuration["Environment:Database:Name"],
Database = configuration["Environment:Database:Name"],
TrustServerCertificate = bool.Parse(configuration["Environment:Database:TrustServerCertificate"] ?? "false")
};
@@ -25,16 +26,16 @@ public class Database(IConfiguration configuration)
{
var connectionString = GetConnectionString();
DbUp.EnsureDatabase.For.SqlDatabase(connectionString);
DbUp.EnsureDatabase.For.PostgresqlDatabase(connectionString);
var upgradeEngine = DeployChanges.To.SqlDatabase(connectionString).WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly(), s => s.Contains(".Schema.")).LogToConsole().Build();
var upgradeEngine = DeployChanges.To.PostgresqlDatabase(connectionString).WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly(), s => s.Contains(".Schema.")).LogToConsole().Build();
upgradeEngine.PerformUpgrade();
}
private SqlConnection CreateConnection()
private NpgsqlConnection CreateConnection()
{
var connection = new SqlConnection(GetConnectionString());
var connection = new NpgsqlConnection(GetConnectionString());
connection.Open();
return connection;

View File

@@ -1,8 +1,19 @@
BEGIN TRANSACTION
INSERT Reading
(Timestamp, Name, Model, Temperature, Pressure, Humidity, Luminance, GasResistance, ColorTemperature, AirQualityIndex)
SELECT
INSERT INTO
reading
(
time,
name,
model,
temperature,
pressure,
humidity,
luminance,
gas_resistance,
color_temperature,
air_quality_index
)
VALUES
(
@Timestamp,
@Name,
@Model,
@@ -13,13 +24,7 @@ SELECT
@GasResistance,
@ColorTemperature,
@AirQualityIndex
WHERE NOT EXISTS
(
SELECT
1
FROM
Reading WITH (UPDLOCK, SERIALIZABLE)
WHERE Timestamp = @Timestamp AND Name = @Name AND Model = @Model
)
COMMIT TRANSACTION
ON CONFLICT
ON CONSTRAINT reading_pk
DO NOTHING

View File

@@ -1,14 +1,17 @@
CREATE TABLE Reading
(
Timestamp datetimeoffset NOT NULL,
Name nvarchar(50) NOT NULL,
Model nvarchar(50) NOT NULL,
Temperature decimal(5, 2) NOT NULL,
Pressure decimal(6, 2) NOT NULL,
Humidity decimal(5, 2) NOT NULL,
Luminance int NOT NULL,
GasResistance int NOT NULL,
ColorTemperature int NOT NULL,
AirQualityIndex decimal(4, 1) NOT NULL,
CONSTRAINT reading_pk PRIMARY KEY (Timestamp, Name, Model)
CREATE TABLE
reading (
time timestamptz NOT NULL,
name text NOT NULL,
model text NOT NULL,
temperature DECIMAL NOT NULL,
pressure DECIMAL NOT NULL,
humidity DECIMAL NOT NULL,
luminance INT NOT NULL,
gas_resistance INT NOT NULL,
color_temperature INT NOT NULL,
air_quality_index DECIMAL NOT NULL,
CONSTRAINT reading_pk PRIMARY KEY (time, name, model)
);
SELECT
create_hypertable('reading', by_range('time'));

View File

@@ -14,7 +14,7 @@ public class MessageHandler : IHostedService
private readonly MqttFactory _mqttFactory;
private readonly string _topic;
private readonly HubConnection _hubConnection;
private readonly HubConnection? _hubConnection;
public MessageHandler(IConfiguration configuration, Database database)
{
@@ -33,11 +33,15 @@ public class MessageHandler : IHostedService
_mqttClient.ApplicationMessageReceivedAsync += OnApplicationMessageReceivedAsync;
_hubConnection = new HubConnectionBuilder().WithUrl(configuration["Environment:Hub:Url"] ?? string.Empty).Build();
var hubUrl = configuration["Environment:Hub:Url"];
if (!string.IsNullOrEmpty(hubUrl))
_hubConnection = new HubConnectionBuilder().WithUrl(hubUrl).Build();
}
public async Task StartAsync(CancellationToken cancellationToken)
{
if (_hubConnection != null)
await _hubConnection.StartAsync(cancellationToken);
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer(_configuration["Mqtt:Server"]).Build();
@@ -51,6 +55,7 @@ public class MessageHandler : IHostedService
{
await _mqttClient.DisconnectAsync(new MqttClientDisconnectOptionsBuilder().Build(), cancellationToken);
if (_hubConnection != null)
await _hubConnection.StopAsync(cancellationToken);
}
@@ -75,6 +80,9 @@ public class MessageHandler : IHostedService
{
try
{
if (_hubConnection == null)
return;
if (_hubConnection.State == HubConnectionState.Disconnected)
await _hubConnection.StartAsync();

View File

@@ -20,9 +20,9 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="ChrisKaczor.Common.OpenTelemetry" Version="1.0.1" />
<PackageReference Include="ChrisKaczor.Common.OpenTelemetry" Version="1.0.2" />
<PackageReference Include="Dapper" Version="2.1.28" />
<PackageReference Include="dbup-sqlserver" Version="5.0.37" />
<PackageReference Include="dbup-postgresql" Version="5.0.40" />
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.1" />
<PackageReference Include="MQTTnet.AspNetCore" Version="4.3.3.952" />

View File

@@ -15,9 +15,9 @@
"Host": "",
"User": "",
"Password": "",
"Name": "Environment",
"Name": "environment",
"TrustServerCertificate": true,
"Port": 1435
"Port": 5432
},
"Hub": {
"Url": "http://hub-server/environment"

View File

@@ -19,27 +19,31 @@ spec:
spec:
containers:
- name: environment-database
image: mcr.microsoft.com/mssql/server
terminationMessagePath: "/dev/termination-log"
terminationMessagePolicy: File
image: timescale/timescaledb:latest-pg16
imagePullPolicy: IfNotPresent
env:
- name: SA_PASSWORD
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: environment-database-credentials
key: username
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: environment-database-credentials
key: password
- name: ACCEPT_EULA
value: "Y"
- name: MSSQL_PID
value: Express
- name: MSSQL_TCP_PORT
value: "1435"
- name: TZ
value: America/New_York
- name: POSTGRES_DB
value: environment
volumeMounts:
- name: data
mountPath: /var/opt/mssql
mountPath: /var/lib/postgresql/data
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
@@ -63,7 +67,7 @@ metadata:
spec:
ports:
- name: client
port: 1435
port: 5432
selector:
app: environment-database
type: LoadBalancer
@@ -108,6 +112,13 @@ spec:
key: password
- name: Environment__Hub__Url
value: http://hub-service/environment
resources:
limits:
cpu: 1
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst