feat: add sqlite database integration

This allows save networks to db & filter them both on input and output
This commit is contained in:
cuqmbr 2022-08-13 21:55:15 +03:00
parent 342b6dc0ef
commit c2b82bb0c3
4 changed files with 206 additions and 6 deletions

View File

@ -11,7 +11,7 @@ public sealed class DatabaseContext : DbContext
private string DbPath { get; }
public DatabaseContext()
public DatabaseContext(string dbName = "netxml2kml.sqlite3.db")
{
var folder = Environment.SpecialFolder.LocalApplicationData;
var path = Path.Join(Environment.GetFolderPath(folder), "netxml2kml");
@ -21,7 +21,8 @@ public sealed class DatabaseContext : DbContext
Directory.CreateDirectory(path);
}
DbPath = Path.Join(path, "netxml2kml.sqlite3.db");
DbPath = Path.Join(path, dbName);
Database.EnsureCreated();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)

View File

@ -1,3 +1,5 @@
using Microsoft.EntityFrameworkCore;
using netxml2kml.Data;
using netxml2kml.Models;
namespace netxml2kml.Methods;
@ -5,13 +7,193 @@ namespace netxml2kml.Methods;
public static class CliOptionsHandlers
{
public static void UniversalHandler(FileInfo? inputFile,
FileInfo? outputFile)
FileInfo? outputFile, bool useDatabase, string? sqlQuery)
{
if (inputFile != null && outputFile != null)
{
var wirelessNetworks = Helpers.DeserializeXml(inputFile);
if (useDatabase)
{
AddWirelessNetworksToDatabase(wirelessNetworks);
}
if (sqlQuery != null)
{
FilterWirelessNetworksInMemory(ref wirelessNetworks, sqlQuery);
}
var kmlString = GetKmlString(wirelessNetworks);
Helpers.WriteStringToFile(kmlString, outputFile);
}
else if (inputFile != null && outputFile == null && useDatabase)
{
var wirelessNetworks = Helpers.DeserializeXml(inputFile);
if (sqlQuery != null)
{
FilterWirelessNetworksInMemory(ref wirelessNetworks, sqlQuery);
}
AddWirelessNetworksToDatabase(wirelessNetworks);
}
else if (inputFile == null && outputFile != null && useDatabase)
{
string kmlString;
if (sqlQuery != null)
{
kmlString = GetKmlString(FilterWirelessNetworksFromDatabase(sqlQuery));
}
else
{
kmlString = GetKmlString(FilterWirelessNetworksFromDatabase("SELECT * FROM WirelessNetworks"));
}
Helpers.WriteStringToFile(kmlString, outputFile);
}
else if (inputFile == null && outputFile == null && useDatabase &&
sqlQuery != null)
{
using var dbContext = new DatabaseContext();
Console.WriteLine(dbContext.Database.ExecuteSqlRaw(sqlQuery));
}
}
private static string GenerateKml(WirelessNetwork[] wirelessNetworks)
private static string GetKmlString(IEnumerable<WirelessNetwork> wirelessNetworks)
{
return "test";
}
private static void AddWirelessNetworksToDatabase(IEnumerable<WirelessNetwork> wirelessNetworks)
{
using var dbContext = new DatabaseContext();
foreach (var wirelessNetwork in wirelessNetworks)
{
// If wireless network has wireless clients add all clients to
// the database or update their LastUpdateDate
if (wirelessNetwork.WirelessConnections != null)
{
foreach (var wirelessConnection in wirelessNetwork.WirelessConnections)
{
var client = wirelessConnection.WirelessClient;
// Add new client to the DB if it is not present
if (!dbContext.WirelessClients.Any(wc =>
wc.Mac == client.Mac))
{
dbContext.WirelessClients.Add(client);
}
// Update LastUpdateDate if the client is present in the DB
else if (dbContext.WirelessClients.Any(wc =>
wc.Mac == client.Mac))
{
var dbClient = dbContext.WirelessClients
.First(wc => wc.Mac == client.Mac);
if (dbClient.LastUpdateDate < client.FirstSeenDate)
{
dbClient.LastUpdateDate = client.FirstSeenDate;
}
}
}
}
// If wireless network has wireless clients add a wireless
// connections to the database or update their LastUpdateDate
if (wirelessNetwork.WirelessConnections != null)
{
foreach (var wirelessConnection in wirelessNetwork.WirelessConnections)
{
var client = wirelessConnection.WirelessClient;
// Add new connection to the DB if it is not present
if (!dbContext.WirelessConnections.Any(wc =>
wc.WirelessClientMac == client.Mac &&
wc.WirelessNetworkBssid == wirelessNetwork.Bssid))
{
dbContext.WirelessConnections.Add(new WirelessConnection
{
WirelessClientMac = client.Mac,
WirelessNetworkBssid = wirelessNetwork.Bssid,
FirstSeenDate = client.FirstSeenDate,
LastUpdateDate = client.LastUpdateDate
});
}
// Update LastUpdateDate if the connection is present in the DB
else if (dbContext.WirelessConnections.Any(wc =>
wc.WirelessClientMac == client.Mac &&
wc.WirelessNetworkBssid == wirelessNetwork.Bssid))
{
var dbConnection = dbContext.WirelessConnections.First(
wc => wc.WirelessClientMac == client.Mac &&
wc.WirelessNetworkBssid == wirelessNetwork.Bssid);
var connectedClient = wirelessNetwork
.WirelessConnections
.First(wc => wc.WirelessClient.Mac == client.Mac)
.WirelessClient;
if (dbConnection.LastUpdateDate < connectedClient.FirstSeenDate)
{
dbConnection.LastUpdateDate =
connectedClient.FirstSeenDate;
}
}
}
}
// Set wireless connections to null since we manually added
// connections to the database context
wirelessNetwork.WirelessConnections = null;
// Add new network to the DB if it is not present
if (!dbContext.WirelessNetworks.Any(wn =>
wn.Bssid == wirelessNetwork.Bssid))
{
dbContext.Add(wirelessNetwork);
}
// Update LastUpdateDate & MaxSignalDmb if
// the network is present in the DB
else if (dbContext.WirelessNetworks.Any(wn =>
wn.Bssid == wirelessNetwork.Bssid))
{
var dbNetwork = dbContext.WirelessNetworks.First(wn =>
wn.Bssid == wirelessNetwork.Bssid);
if (dbNetwork.MaxSignalDbm < wirelessNetwork.MaxSignalDbm)
{
dbNetwork.MaxLatitude = wirelessNetwork.MaxLatitude;
dbNetwork.MaxLongitude = wirelessNetwork.MaxLongitude;
dbNetwork.MaxAltitude = wirelessNetwork.MaxAltitude;
dbNetwork.MaxSignalDbm = wirelessNetwork.MaxSignalDbm;
}
if (dbNetwork.LastUpdateDate < wirelessNetwork.FirstSeenDate)
{
dbNetwork.LastUpdateDate = wirelessNetwork.FirstSeenDate;
}
}
}
dbContext.SaveChanges();
}
private static void FilterWirelessNetworksInMemory(
ref WirelessNetwork[] wirelessNetworks, string sqlQuery)
{
using var dbContext = new DatabaseContext("InMemoryFiltering.sqlite3.db");
dbContext.WirelessNetworks.AddRange(wirelessNetworks);
dbContext.SaveChanges();
wirelessNetworks = dbContext.WirelessNetworks.FromSqlRaw(sqlQuery).ToArray();
dbContext.Database.EnsureDeleted();
}
private static WirelessNetwork[] FilterWirelessNetworksFromDatabase(string sqlQuery)
{
using var dbContext = new DatabaseContext();
return dbContext.WirelessNetworks.FromSqlRaw(sqlQuery).ToArray();
}
}

View File

@ -102,4 +102,11 @@ public static class Helpers
return new DateTime(year, month, day, hour, minute, second);
}
public static void WriteStringToFile(string str, FileInfo file)
{
var writer = new StreamWriter(file.OpenWrite());
writer.Write(str);
writer.Close();
}
}

View File

@ -17,12 +17,22 @@ class Program
aliases: new[] {"-o", "--output"},
description: "The name of the file to be created.");
var databaseOption = new Option<bool>(
aliases: new[] {"-d", "--use-database"},
description: "Use database. Save/retrieve wireless networks and clients to/from sqlite database.");
var queryOption = new Option<string?>(
aliases: new[] {"-q", "--query"},
description: "Filter input using sql query.");
var rootCommand = new RootCommand("netxml2kml .netxml to .kml converter.");
rootCommand.AddOption(inputOption);
rootCommand.AddOption(outputOption);
rootCommand.AddOption(databaseOption);
rootCommand.AddOption(queryOption);
rootCommand.SetHandler(CliOptionsHandlers.UniversalHandler,
inputOption, outputOption);
inputOption, outputOption, databaseOption, queryOption);
return await rootCommand.InvokeAsync(args);
}