kopia lustrzana https://github.com/dl2alf/AirScout
404 wiersze
15 KiB
C#
404 wiersze
15 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.IO;
|
|
using System.Globalization;
|
|
using System.Reflection;
|
|
using System.Data;
|
|
using System.Diagnostics;
|
|
using ScoutBase.Core;
|
|
using ScoutBase.Database;
|
|
using System.Data.SQLite;
|
|
using Newtonsoft.Json;
|
|
using System.Windows.Forms;
|
|
using System.ComponentModel;
|
|
|
|
namespace AirScout.Signals
|
|
{
|
|
|
|
public class SignalData
|
|
{
|
|
static SignalDatabase signals = new SignalDatabase();
|
|
public static SignalDatabase Database
|
|
{
|
|
get
|
|
{
|
|
return signals;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Holds the signal information in a database structure.
|
|
/// </summary>
|
|
public class SignalDatabase : ScoutBaseDatabase
|
|
{
|
|
public SignalDatabase()
|
|
{
|
|
UserVersion = 1;
|
|
Name = "Scoutbase Signal Database";
|
|
Description = "Holds recorded signal strength information";
|
|
db = OpenDatabase("signals.db3", DefaultDatabaseDirectory(), Properties.Settings.Default.Database_InMemory);
|
|
// set auto vacuum mode to "Full" to allow database to reduce size on disk
|
|
// requires a vacuum command to change database layout
|
|
AUTOVACUUMMODE mode = db.GetAutoVacuum();
|
|
if (mode != AUTOVACUUMMODE.FULL)
|
|
{
|
|
if (MessageBox.Show("A major database layout change is necessary to run this version of AirScout. Older versions of AirScout are not compatible anymore and will cause errors. \n\nPress >OK< to start upgrade now (this will take some minutes). \nPress >Cancel< to leave.", "Database Upgrade of " + Path.GetFileName(db.DBLocation), MessageBoxButtons.OKCancel) == DialogResult.Cancel)
|
|
Environment.Exit(-1); // exit immediately
|
|
db.SetAutoVacuum(AUTOVACUUMMODE.FULL);
|
|
}
|
|
// create tables with schemas if not exist
|
|
if (!SignalLevelTableExists())
|
|
SignalLevelCreateTable();
|
|
}
|
|
|
|
~SignalDatabase()
|
|
{
|
|
CloseDatabase(db);
|
|
}
|
|
|
|
public string DefaultDatabaseDirectory()
|
|
{
|
|
// create default database directory name
|
|
string dir = Properties.Settings.Default.Database_Directory;
|
|
if (!String.IsNullOrEmpty(dir))
|
|
{
|
|
return dir;
|
|
}
|
|
// empty settings -_> create standard path
|
|
// collect entry assembly info
|
|
Assembly ass = Assembly.GetExecutingAssembly();
|
|
string company = "";
|
|
string product = "";
|
|
object[] attribs;
|
|
attribs = ass.GetCustomAttributes(typeof(AssemblyCompanyAttribute), true);
|
|
if (attribs.Length > 0)
|
|
{
|
|
company = ((AssemblyCompanyAttribute)attribs[0]).Company;
|
|
}
|
|
attribs = ass.GetCustomAttributes(typeof(AssemblyProductAttribute), true);
|
|
if (attribs.Length > 0)
|
|
{
|
|
product = ((AssemblyProductAttribute)attribs[0]).Product;
|
|
}
|
|
// create database path
|
|
dir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
|
if (!String.IsNullOrEmpty(company))
|
|
dir = Path.Combine(dir, company);
|
|
if (!String.IsNullOrEmpty(product))
|
|
dir = Path.Combine(dir, product);
|
|
return Path.Combine(dir, "AircraftData");
|
|
}
|
|
|
|
#region SignalLevel
|
|
|
|
public bool SignalLevelTableExists(string tablename = "")
|
|
{
|
|
// check for table name is null or empty --> use default tablename from type instead
|
|
string tn = tablename;
|
|
if (String.IsNullOrEmpty(tn))
|
|
tn = SignalLevelDesignator.TableName;
|
|
return db.TableExists(tn);
|
|
}
|
|
|
|
public void SignalLevelCreateTable(string tablename = "")
|
|
{
|
|
lock (db.DBCommand)
|
|
{
|
|
// check for table name is null or empty --> use default tablename from type instead
|
|
string tn = tablename;
|
|
if (String.IsNullOrEmpty(tn))
|
|
tn = SignalLevelDesignator.TableName;
|
|
db.DBCommand.CommandText = "CREATE TABLE `" + tn + "`(Level DOUBLE, LastUpdated INT32, PRIMARY KEY (LastUpdated))";
|
|
db.DBCommand.Parameters.Clear();
|
|
db.Execute(db.DBCommand);
|
|
}
|
|
}
|
|
|
|
public long SignalLevelCount()
|
|
{
|
|
object count = db.ExecuteScalar("SELECT COUNT(*) FROM " + SignalLevelDesignator.TableName);
|
|
if (IsValid(count))
|
|
return (long)count;
|
|
return 0;
|
|
}
|
|
|
|
public bool SignalLevelExists(DateTime lastupdated)
|
|
{
|
|
SignalLevelDesignator sd = new SignalLevelDesignator(lastupdated);
|
|
return SignalLevelExists(sd);
|
|
}
|
|
|
|
public bool SignalLevelExists(SignalLevelDesignator sd)
|
|
{
|
|
lock (db.DBCommand)
|
|
{
|
|
db.DBCommand.CommandText = "SELECT EXISTS (SELECT LastUpdated FROM " + SignalLevelDesignator.TableName + " WHERE LastUpdated = @LastUpdated";
|
|
db.DBCommand.Parameters.Clear();
|
|
db.DBCommand.Parameters.Add(sd.AsUNIXTime("LastUpdated"));
|
|
object result = db.DBCommand.ExecuteScalar();
|
|
if (IsValid(result) && ((long)result > 0))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public SignalLevelDesignator SignalLevelFind(DateTime lastupdated)
|
|
{
|
|
SignalLevelDesignator sd = new SignalLevelDesignator(lastupdated);
|
|
return SignalLevelFind(sd);
|
|
}
|
|
|
|
public SignalLevelDesignator SignalLevelFind(SignalLevelDesignator sd)
|
|
{
|
|
lock (db.DBCommand)
|
|
{
|
|
db.DBCommand.CommandText = "SELECT * FROM " + SignalLevelDesignator.TableName + " WHERE LastUpdated = @LastUpdated";
|
|
db.DBCommand.Parameters.Clear();
|
|
db.DBCommand.Parameters.Add(sd.AsUNIXTime("LastUpdated"));
|
|
try
|
|
{
|
|
DataTable Result = db.Select(db.DBCommand);
|
|
if ((Result != null) && (Result.Rows.Count > 0))
|
|
{
|
|
return new SignalLevelDesignator(Result.Rows[0]);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.WriteMessage(ex.ToString(), LogLevel.Error);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public SignalLevelDesignator SignalLevelFindAt(long index)
|
|
{
|
|
lock (db.DBCommand)
|
|
{
|
|
db.DBCommand.CommandText = "SELECT * FROM " + SignalLevelDesignator.TableName + " LIMIT 1 OFFSET " + index.ToString();
|
|
db.DBCommand.Parameters.Clear();
|
|
try
|
|
{
|
|
DataTable Result = db.Select(db.DBCommand);
|
|
if ((Result != null) && (Result.Rows.Count > 0))
|
|
{
|
|
return new SignalLevelDesignator(Result.Rows[0]);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.WriteMessage(ex.ToString(), LogLevel.Error);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public DateTime SignalLevelFindlastUpdated(DateTime lastupdated)
|
|
{
|
|
SignalLevelDesignator sd = new SignalLevelDesignator(lastupdated);
|
|
return SignalLevelFindLastUpdated(sd);
|
|
}
|
|
|
|
public DateTime SignalLevelFindLastUpdated(SignalLevelDesignator sd)
|
|
{
|
|
lock (db.DBCommand)
|
|
{
|
|
db.DBCommand.CommandText = "SELECT LastUpdated FROM " + SignalLevelDesignator.TableName + " WHERE LastUpdated = @LastUpdated";
|
|
db.DBCommand.Parameters.Clear();
|
|
db.DBCommand.Parameters.Add(sd.AsUNIXTime("LastUpdated"));
|
|
object result = db.ExecuteScalar(db.DBCommand);
|
|
if (IsValid(result))
|
|
return (SQLiteEntry.UNIXTimeToDateTime((int)result));
|
|
}
|
|
return DateTime.MinValue;
|
|
}
|
|
|
|
public int SignalLevelInsert(SignalLevelDesignator sd)
|
|
{
|
|
lock (db.DBCommand)
|
|
{
|
|
db.DBCommand.CommandText = "INSERT INTO " + SignalLevelDesignator.TableName + " (Level, LastUpdated) VALUES (@Level, @LastUpdated)";
|
|
db.DBCommand.Parameters.Clear();
|
|
db.DBCommand.Parameters.Add(sd.AsDouble("Level"));
|
|
db.DBCommand.Parameters.Add(sd.AsUNIXTime("LastUpdated"));
|
|
return db.ExecuteNonQuery(db.DBCommand);
|
|
}
|
|
}
|
|
|
|
public int SignalLevelDelete(DateTime lastupdated)
|
|
{
|
|
SignalLevelDesignator sd = new SignalLevelDesignator(lastupdated);
|
|
return SignalLevelDelete(sd);
|
|
}
|
|
|
|
public int SignalLevelDelete(SignalLevelDesignator sd)
|
|
{
|
|
lock (db.DBCommand)
|
|
{
|
|
db.DBCommand.CommandText = "DELETE FROM " + SignalLevelDesignator.TableName + " WHERE LastUpdated = @LastUpdated";
|
|
db.DBCommand.Parameters.Clear();
|
|
db.DBCommand.Parameters.Add(sd.AsUNIXTime("LastUpdated"));
|
|
return db.ExecuteNonQuery(db.DBCommand);
|
|
}
|
|
}
|
|
|
|
public int SignalLevelDeleteAll()
|
|
{
|
|
lock (db.DBCommand)
|
|
{
|
|
db.DBCommand.CommandText = "DELETE FROM " + SignalLevelDesignator.TableName;
|
|
db.DBCommand.Parameters.Clear();
|
|
return db.ExecuteNonQuery(db.DBCommand);
|
|
}
|
|
}
|
|
|
|
public int SignalLevelUpdate(SignalLevelDesignator sd)
|
|
{
|
|
lock (db.DBCommand)
|
|
{
|
|
db.DBCommand.CommandText = "UPDATE " + SignalLevelDesignator.TableName + " SET Level = @Level, LastUpdated = @LastUpdated WHERE LastUpdated = @LastUpdated";
|
|
db.DBCommand.Parameters.Clear();
|
|
db.DBCommand.Parameters.Add(sd.AsDouble("Level"));
|
|
db.DBCommand.Parameters.Add(sd.AsUNIXTime("LastUpdated"));
|
|
return db.ExecuteNonQuery(db.DBCommand);
|
|
}
|
|
}
|
|
|
|
public int SignalLevelBulkInsert(List<SignalLevelDesignator> sds)
|
|
{
|
|
int errors = 0;
|
|
try
|
|
{
|
|
lock (db)
|
|
{
|
|
db.BeginTransaction();
|
|
foreach (SignalLevelDesignator sd in sds)
|
|
{
|
|
try
|
|
{
|
|
SignalLevelInsert(sd);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.WriteMessage("Error inserting SignalLevel at [" + sd.LastUpdated.ToString("yyyy-MM-dd HH:mm:ss") + "]: " + ex.ToString(), LogLevel.Error);
|
|
errors++;
|
|
}
|
|
}
|
|
db.Commit();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.WriteMessage(ex.ToString(), LogLevel.Error);
|
|
}
|
|
return -errors;
|
|
}
|
|
|
|
public int SignalLevelBulkDelete(List<SignalLevelDesignator> sds)
|
|
{
|
|
int errors = 0;
|
|
try
|
|
{
|
|
lock (db)
|
|
{
|
|
db.BeginTransaction();
|
|
foreach (SignalLevelDesignator sd in sds)
|
|
{
|
|
try
|
|
{
|
|
SignalLevelDelete(sd);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.WriteMessage("Error deleting SignalLevel at [" + sd.LastUpdated.ToString("yyyy-MM-dd HH:mm:ss") + "]: " + ex.ToString(), LogLevel.Error);
|
|
errors++;
|
|
}
|
|
}
|
|
db.Commit();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.WriteMessage(ex.ToString(), LogLevel.Error);
|
|
}
|
|
return -errors;
|
|
}
|
|
|
|
public int SignalLevelBulkInsertOrUpdateIfNewer(List<SignalLevelDesignator> sds)
|
|
{
|
|
if (sds == null)
|
|
return 0;
|
|
int i = 0;
|
|
lock (db)
|
|
{
|
|
db.BeginTransaction();
|
|
foreach (SignalLevelDesignator sd in sds)
|
|
{
|
|
SignalLevelInsertOrUpdateIfNewer(sd);
|
|
i++;
|
|
}
|
|
db.Commit();
|
|
}
|
|
return i;
|
|
}
|
|
|
|
public int SignalLevelInsertOrUpdateIfNewer(SignalLevelDesignator sd)
|
|
{
|
|
DateTime dt = SignalLevelFindLastUpdated(sd);
|
|
if (dt == DateTime.MinValue)
|
|
return SignalLevelInsert(sd);
|
|
if (dt < sd.LastUpdated)
|
|
return SignalLevelUpdate(sd);
|
|
return 0;
|
|
}
|
|
|
|
public List<SignalLevelDesignator> SignalLevelGetAll()
|
|
{
|
|
List<SignalLevelDesignator> l = new List<SignalLevelDesignator>();
|
|
DataTable Result = db.Select("SELECT * FROM " + SignalLevelDesignator.TableName);
|
|
if (!IsValid(Result) || (Result.Rows.Count == 0))
|
|
return l;
|
|
foreach (DataRow row in Result.Rows)
|
|
l.Add(new SignalLevelDesignator(row));
|
|
return l;
|
|
|
|
}
|
|
|
|
public List<SignalLevelDesignator> SignalLevelFromJSON(string json)
|
|
{
|
|
if (String.IsNullOrEmpty(json))
|
|
return null;
|
|
JsonSerializerSettings settings = new JsonSerializerSettings();
|
|
settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
|
|
settings.FloatFormatHandling = FloatFormatHandling.String;
|
|
settings.Formatting = Newtonsoft.Json.Formatting.Indented;
|
|
return JsonConvert.DeserializeObject<List<SignalLevelDesignator>>(json, settings);
|
|
}
|
|
|
|
public string SignalLevelToJSON()
|
|
{
|
|
List<SignalLevelDesignator> l = SignalLevelGetAll();
|
|
JsonSerializerSettings settings = new JsonSerializerSettings();
|
|
settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
|
|
settings.FloatFormatHandling = FloatFormatHandling.String;
|
|
settings.Formatting = Newtonsoft.Json.Formatting.Indented;
|
|
string json = JsonConvert.SerializeObject(l, settings);
|
|
return json;
|
|
}
|
|
|
|
public DataTableSignalLevels SignalLevelToDataTable()
|
|
{
|
|
List<SignalLevelDesignator> sds = SignalLevelGetAll();
|
|
DataTableSignalLevels dtl = new DataTableSignalLevels(sds);
|
|
return dtl;
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
}
|