Add ISO-4217 table.

This commit is contained in:
2020-06-10 20:36:38 +01:00
parent a6901b8e6b
commit 6d5f613252
9 changed files with 4524 additions and 1 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Marechai.Database.Migrations
{
public partial class AddIso4217 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable("Iso4217", table => new
{
Code = table.Column<string>(maxLength: 3, nullable: false),
Numeric = table.Column<short>("smallint(3)", nullable: false),
MinorUnits = table.Column<byte>(nullable: true),
Name = table.Column<string>(maxLength: 150, nullable: false),
Withdrawn = table.Column<DateTime>(nullable: true)
}, constraints: table =>
{
table.PrimaryKey("PK_Iso4217", x => x.Code);
});
migrationBuilder.CreateIndex("IX_Iso4217_Numeric", "Iso4217", "Numeric");
migrationBuilder.CreateIndex("IX_Iso4217_Withdrawn", "Iso4217", "Withdrawn");
}
protected override void Down(MigrationBuilder migrationBuilder) => migrationBuilder.DropTable("Iso4217");
}
}

View File

@@ -813,6 +813,28 @@ namespace Marechai.Database.Migrations
b.ToTable("iso3166_1_numeric");
});
modelBuilder.Entity("Marechai.Database.Models.Iso4217", b =>
{
b.Property<string>("Code").HasColumnType("varchar(3) CHARACTER SET utf8mb4").HasMaxLength(3);
b.Property<byte?>("MinorUnits").HasColumnType("tinyint unsigned");
b.Property<string>("Name").IsRequired().HasColumnType("varchar(150) CHARACTER SET utf8mb4").
HasMaxLength(150);
b.Property<short>("Numeric").HasColumnType("smallint(3)");
b.Property<DateTime?>("Withdrawn").HasColumnType("datetime(6)");
b.HasKey("Code");
b.HasIndex("Numeric");
b.HasIndex("Withdrawn");
b.ToTable("Iso4217");
});
modelBuilder.Entity("Marechai.Database.Models.Iso639", b =>
{
b.Property<string>("Id").HasColumnType("char(3)");

View File

@@ -0,0 +1,19 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Marechai.Database.Models
{
public class Iso4217
{
[StringLength(3), Required, Key]
public string Code { get; set; }
[Column(TypeName = "smallint(3)"), Required]
public short Numeric { get; set; }
public byte? MinorUnits { get; set; }
[StringLength(150), Required]
public string Name { get; set; }
[DataType(DataType.Date)]
public DateTime? Withdrawn { get; set; }
}
}

View File

@@ -96,6 +96,7 @@ namespace Marechai.Database.Models
public virtual DbSet<StorageByMachine> StorageByMachine { get; set; }
public virtual DbSet<StorageByOwnedMachine> StorageByOwnedMachine { get; set; }
public virtual DbSet<Audit> Audit { get; set; }
public virtual DbSet<Iso4217> Iso4217 { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
@@ -1552,6 +1553,12 @@ namespace Marechai.Database.Models
entity.HasIndex(d => d.Table);
entity.HasIndex(d => d.Type);
});
modelBuilder.Entity<Iso4217>(entity =>
{
entity.HasIndex(d => d.Numeric);
entity.HasIndex(d => d.Withdrawn);
});
}
}
}

View File

@@ -0,0 +1,42 @@
using System;
using System.Xml.Serialization;
namespace Marechai.Database.Schemas
{
public class Iso4217Xml
{
[XmlRoot(ElementName = "ISO_4217")]
public class Root
{
[XmlAttribute(AttributeName = "Pblshd", DataType = "date")]
public DateTime Published { get; set; }
[XmlArray("CcyTbl"), XmlArrayItem("CcyNtry", typeof(Currency), IsNullable = true)]
public Currency[] Current { get; set; }
[XmlArray("HstrcCcyTbl"), XmlArrayItem("HstrcCcyNtry", typeof(Currency), IsNullable = true)]
public Currency[] Historical { get; set; }
}
public class Currency
{
[XmlElement("CtryNm")]
public string Country { get; set; }
[XmlElement("Ccy")]
public string Code { get; set; }
[XmlElement("CcyNbr")]
public short Number { get; set; }
[XmlElement("CcyMnrUnts", IsNullable = true)]
public string MinorUnits { get; set; }
[XmlElement("CcyNm")]
public string Name { get; set; }
[XmlElement("WthdrwlDt", IsNullable = true)]
public string Withdrawn { get; set; }
}
}
}

View File

@@ -53,6 +53,25 @@ namespace Marechai.Database.Seeders
end = DateTime.Now;
Console.WriteLine("\u001b[31;1mTook \u001b[32;1m{0} seconds\u001b[31;1m...\u001b[0m",
(end - start).TotalSeconds);
start = DateTime.Now;
Console.WriteLine("\u001b[31;1mImporting ISO-4217 codes...\u001b[0m");
try
{
Iso4217.Seed(context);
}
catch(Exception e)
{
Console.WriteLine("Exception {0} importing ISO-4217 codes, saving changes and continuing...", e);
}
context.SaveChanges();
end = DateTime.Now;
Console.WriteLine("\u001b[31;1mTook \u001b[32;1m{0} seconds\u001b[31;1m...\u001b[0m",
(end - start).TotalSeconds);

View File

@@ -0,0 +1,195 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Xml.Serialization;
using Marechai.Database.Models;
using Marechai.Database.Schemas;
namespace Marechai.Database.Seeders
{
public class Iso4217
{
// Lists from https://www.currency-iso.org/en/home/tables/table-a1.html
public static void Seed(MarechaiContext context)
{
if(!Directory.Exists("iso4217"))
return;
var codes = new Iso4217Xml.Root();
try
{
if(File.Exists(Path.Combine("iso4217", "list_one.xml")))
{
using var sr = new StreamReader(Path.Combine("iso4217", "list_one.xml"));
var xs = new XmlSerializer(typeof(Iso4217Xml.Root));
var listOne = (Iso4217Xml.Root)xs.Deserialize(sr);
if(listOne.Published > codes.Published)
codes.Published = listOne.Published;
codes.Current = listOne.Current;
}
}
catch(Exception e)
{
Console.WriteLine("Exception trying to read list one.");
}
try
{
if(File.Exists(Path.Combine("iso4217", "list_three.xml")))
{
using var sr = new StreamReader(Path.Combine("iso4217", "list_three.xml"));
var xs = new XmlSerializer(typeof(Iso4217Xml.Root));
var listThree = (Iso4217Xml.Root)xs.Deserialize(sr);
if(listThree.Published > codes.Published)
codes.Published = listThree.Published;
codes.Historical = listThree.Historical;
}
}
catch(Exception e)
{
Console.WriteLine("Exception trying to read list three.");
}
if(codes.Current is null &&
codes.Historical is null)
{
Console.WriteLine("No ISO-4217 codes could be read.");
return;
}
Dictionary<string, Models.Iso4217> existingCodes = context.Iso4217.ToDictionary(c => c.Code);
Dictionary<string, Models.Iso4217> newCodes = new Dictionary<string, Models.Iso4217>();
long modified = 0;
codes.Current ??= new Iso4217Xml.Currency[0];
codes.Historical ??= new Iso4217Xml.Currency[0];
foreach(Iso4217Xml.Currency currency in codes.Historical)
{
bool changed = false;
byte minorUnits;
DateTime withdrawn;
if(currency.Code is null)
continue;
if(!existingCodes.TryGetValue(currency.Code, out Models.Iso4217 existing))
{
var newCode = new Models.Iso4217
{
Code = currency.Code, Name = currency.Name, Numeric = currency.Number
};
if(byte.TryParse(currency.MinorUnits, out minorUnits))
newCode.MinorUnits = minorUnits;
if(DateTime.TryParseExact(currency.Withdrawn, "yyyy'-'MM", CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal, out withdrawn))
newCode.Withdrawn = withdrawn;
newCodes[currency.Code] = newCode;
existingCodes[currency.Code] = newCode;
continue;
}
if(existing.Code != currency.Code)
{
existing.Code = currency.Code;
changed = true;
}
if(existing.Name != currency.Name)
{
existing.Name = currency.Name;
changed = true;
}
if(byte.TryParse(currency.MinorUnits, out minorUnits) &&
existing.MinorUnits != minorUnits)
{
existing.MinorUnits = minorUnits;
changed = true;
}
if(DateTime.TryParseExact(currency.Withdrawn, "yyyy'-'MM", CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal, out withdrawn) &&
existing.Withdrawn != withdrawn)
{
existing.Withdrawn = withdrawn;
changed = true;
}
if(changed)
modified++;
}
foreach(Iso4217Xml.Currency currency in codes.Current)
{
bool changed = false;
byte minorUnits;
if(currency.Code is null)
continue;
if(!existingCodes.TryGetValue(currency.Code, out Models.Iso4217 existing))
{
var newCode = new Models.Iso4217
{
Code = currency.Code, Name = currency.Name, Numeric = currency.Number
};
if(byte.TryParse(currency.MinorUnits, out minorUnits))
newCode.MinorUnits = minorUnits;
newCodes[currency.Code] = newCode;
existingCodes[currency.Code] = newCode;
continue;
}
if(existing.Code != currency.Code)
{
existing.Code = currency.Code;
changed = true;
}
if(existing.Name != currency.Name)
{
existing.Name = currency.Name;
changed = true;
}
if(byte.TryParse(currency.MinorUnits, out minorUnits) &&
existing.MinorUnits != minorUnits)
{
existing.MinorUnits = minorUnits;
changed = true;
}
if(existing.Withdrawn != null)
{
existing.Withdrawn = null;
changed = true;
}
if(changed)
modified++;
}
context.Iso4217.AddRange(newCodes.Values);
Console.WriteLine("{0} currency codes added", newCodes.Count);
Console.WriteLine("{0} currency codes modified", modified);
}
}
}

View File

@@ -2,7 +2,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Version>4.0.0.1622</Version>
<Version>4.0.0.1647</Version>
<Company>Canary Islands Computer Museum</Company>
<Copyright>Copyright © 2003-2020 Natalia Portillo</Copyright>
<Product>Canary Islands Computer Museum Website</Product>