//
// Class: LocodeDB
// Current CLR: 4.0.30319.42000
// System: Microsoft Visual Studio 10.0
// Author: dani
// Created: 1/9/2016 10:10:20 PM
//
// Copyright (c) 2016 Informatikbüro Daniel Schick. All rights reserved.
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using bsmd.database;
using log4net;
namespace ENI2.Locode
{
///
/// Locodes suchen (zu Orten), die DB ist aus einem github Projekt:
/// https://github.com/kabisa/un_locode
///
public static class LocodeDB
{
private static readonly SQLiteConnection _con;
private const string _locode_DB_NAME = "db.sqlite";
private static readonly ILog _log = LogManager.GetLogger(typeof(LocodeDB));
static LocodeDB()
{
_con = new SQLiteConnection(string.Format("data source={0}; Version=3;", _locode_DB_NAME));
_con.Open();
}
#region public static methods
public static string LocodeGERFromCity(string city)
{
return LocodeDB.LocodeFromCity(city, "DE");
}
///
/// Lookup and create locode from local sqlite database
///
public static string LocodeFromCity(string city, string country)
{
string result = null;
string query = string.Format("SELECT city_code FROM locodes JOIN countries ON locodes.country_id = countries.ID WHERE countries.code = '{0}' AND locodes.port='t' AND (locodes.name like '{1}' OR locodes.name_wo_diacritics like '{1}')",
country, city);
SQLiteCommand cmd = new SQLiteCommand(query, _con);
IDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
result = reader.GetString(0);
break;
}
reader.Close();
cmd.Dispose();
if (result != null)
result = string.Format("{0}{1}", country, result);
return result;
}
public static List AllLocodesForCityName(string city)
{
List results = new List();
if(city.Contains(","))
{
string[] elems = city.Split(',');
string countryCode = CountryCodeFromName(elems[1].Trim());
string lcLookup = LocodeFromCity(elems[0].Trim(), countryCode);
if ((countryCode != null) && (lcLookup != null))
results.Add(lcLookup);
}
string query = string.Format("SELECT city_code, countries.code FROM locodes JOIN countries ON locodes.country_id = countries.ID WHERE locodes.port='t' AND (locodes.name like '{0}' OR locodes.name_wo_diacritics like '{0}')", city);
SQLiteCommand cmd = new SQLiteCommand(query, _con);
IDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
if (!reader.IsDBNull(0) && !reader.IsDBNull(1))
results.Add(string.Format("{0}{1}", reader.GetString(1), reader.GetString(0)));
}
reader.Close();
cmd.Dispose();
return results;
}
public static List AllLocodesForCityNameAsEntries(string city, bool onlyPorts = true)
{
List results = new List();
if (city.Contains(","))
{
string[] elems = city.Split(',');
string countryCode = CountryCodeFromName(elems[1].Trim());
string lcLookup = LocodeFromCity(elems[0].Trim(), countryCode);
if ((countryCode != null) && (lcLookup != null))
{
LocodeEntry entry = new LocodeEntry();
entry.Locode = lcLookup;
entry.Name = elems[0].Trim();
results.Add(entry);
}
}
string query = "SELECT locodes.name_wo_diacritics, city_code, countries.code FROM locodes JOIN countries ON locodes.country_id = countries.ID WHERE locodes.port='t' AND (locodes.name like $PAR OR locodes.name_wo_diacritics like $PAR)";
if(!onlyPorts)
query = "SELECT locodes.name_wo_diacritics, city_code, countries.code FROM locodes JOIN countries ON locodes.country_id = countries.ID WHERE (locodes.name like $PAR OR locodes.name_wo_diacritics like $PAR)";
SQLiteCommand cmd = new SQLiteCommand(query, _con);
cmd.Parameters.AddWithValue("$PAR", city);
IDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
if (!reader.IsDBNull(1) && !reader.IsDBNull(2)) {
LocodeEntry entry = new LocodeEntry();
entry.Locode = string.Format("{0}{1}", reader.GetString(2), reader.GetString(1));
if (!reader.IsDBNull(0))
entry.Name = reader.GetString(0);
results.Add(entry);
}
}
reader.Close();
cmd.Dispose();
return results;
}
///
/// Lookup 2CHAR Country Code from country name (like search). Hopefully this will result in many hits
///
public static string CountryCodeFromName(string countryName)
{
string result = null;
string query = string.Format("SELECT code FROM countries WHERE countries.name like @COUNTRY");
SQLiteCommand cmd = new SQLiteCommand(query, _con);
cmd.Parameters.Add(new SQLiteParameter("@COUNTRY", countryName));
IDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
result = reader.GetString(0);
break;
}
reader.Close();
cmd.Dispose();
return result;
}
///
/// Get Name from LOCODE (any! type of locode, not just ports)
///
public static string NameFromLocode(string locode)
{
if (locode.IsNullOrEmpty()) return null;
if (locode.Length != 5) return null;
string result = null;
try
{
string locodeUpper = locode.ToUpper();
string query = string.Format("SELECT locodes.name_wo_diacritics FROM locodes JOIN countries ON locodes.country_id = countries.ID WHERE locodes.city_code = '{0}' AND countries.code = '{1}'",
locodeUpper.Substring(2), locodeUpper.Substring(0, 2));
SQLiteCommand cmd = new SQLiteCommand(query, _con);
IDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
if (!reader.IsDBNull(0))
result = reader.GetString(0);
break;
}
reader.Close();
cmd.Dispose();
}
catch (Exception ex)
{
_log.WarnFormat("Error on locode lookup: {0}", ex.Message);
}
return result;
}
///
/// Get Portname from LOCODE
///
public static string PortNameFromLocode(string locode)
{
if (locode.IsNullOrEmpty()) return null;
if (locode.Length != 5) return null;
string result = null;
try
{
string locodeUpper = locode.ToUpper();
string query = string.Format("SELECT locodes.name_wo_diacritics FROM locodes JOIN countries ON locodes.country_id = countries.ID WHERE locodes.port='t' AND locodes.city_code = '{0}' AND countries.code = '{1}'",
locodeUpper.Substring(2), locodeUpper.Substring(0, 2));
SQLiteCommand cmd = new SQLiteCommand(query, _con);
IDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
if (!reader.IsDBNull(0))
result = reader.GetString(0);
break;
}
reader.Close();
cmd.Dispose();
}
catch(Exception ex)
{
_log.WarnFormat("Error on locode lookup: {0}", ex.Message);
}
return result;
}
///
/// SSN Portname from Locode (for validation)
///
public static string SSNPortNameFromLocode(string locode)
{
if (locode.IsNullOrEmpty()) return null;
if (locode.Length != 5) return null;
try
{
string result = null;
string query = string.Format("SELECT LocationName FROM SSN_LOCODES WHERE LocationCode = '{0}'", locode);
SQLiteCommand cmd = new SQLiteCommand(query, _con);
IDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
if (!reader.IsDBNull(0))
result = reader.GetString(0);
break;
}
reader.Close();
cmd.Dispose();
return result;
}
catch (Exception ex)
{
_log.WarnFormat("error reading SSN location from locode: {0}", ex.ToString());
return null;
}
}
///
/// Get Locationname from LOCODE
///
///
///
public static string LocationNameFromLocode(string locode)
{
if (locode.IsNullOrEmpty()) return null;
if (locode.Length != 5) return null;
try
{
string result = null;
string query = string.Format("SELECT locodes.name_wo_diacritics FROM locodes JOIN countries ON locodes.country_id = countries.ID WHERE locodes.city_code = '{0}' AND countries.code = '{1}'",
locode.Substring(2), locode.Substring(0, 2));
SQLiteCommand cmd = new SQLiteCommand(query, _con);
IDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
if (!reader.IsDBNull(0))
result = reader.GetString(0);
break;
}
reader.Close();
cmd.Dispose();
return result;
}
catch(Exception ex)
{
_log.WarnFormat("error reading location from locode: {0}", ex.ToString());
return null;
}
}
public static void CloseDB()
{
_con.Close();
}
#endregion
#region class LocodeEntry
public class LocodeEntry : IComparable
{
public string Locode { get; set; }
public string Name { get; set; }
public int CompareTo(object obj)
{
if (obj is LocodeEntry locodeEntry)
return Locode.CompareTo((locodeEntry).Locode);
else
return 0;
}
}
#endregion
}
}