diff --git a/FIAS.Core/API/FIASInfo.cs b/FIAS.Core/API/FIASInfo.cs index 78a626e..7a5fee3 100644 --- a/FIAS.Core/API/FIASInfo.cs +++ b/FIAS.Core/API/FIASInfo.cs @@ -1,6 +1,6 @@ -using Newtonsoft.Json.Converters; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; using System; -using Newtonsoft.Json; namespace FIAS.Core.API { diff --git a/FIAS.Core/Extensions/SQLExtensions.cs b/FIAS.Core/Extensions/SQLExtensions.cs index 591da9f..096b667 100644 --- a/FIAS.Core/Extensions/SQLExtensions.cs +++ b/FIAS.Core/Extensions/SQLExtensions.cs @@ -1,9 +1,5 @@ -using System.Data; -using System.Data.SqlClient; -using System.Globalization; +using System.Data.SqlClient; using System.Linq; -using System.Threading; -using System.Threading.Tasks; namespace FIAS.Core.Extensions { @@ -16,73 +12,6 @@ public static SqlParameter AddParameter(this SqlCommand command, string paramete return command.Parameters.AddWithValue(parameter, value); } - public static void ExecuteNonQuery(this SqlCommand command, string connection) - { - using (var Connection = new SqlConnection(connection)) - { - Connection.Open(); - command.Connection = Connection; - command.ExecuteNonQuery(); - } - } - - public static Task ExecuteNonQueryAsync(this SqlCommand command, string connection) => ExecuteNonQueryAsync(command, connection, default); - - public static async Task ExecuteNonQueryAsync(this SqlCommand command, string connection, CancellationToken token) - { - using (var Connection = new SqlConnection(connection)) - { - Connection.Open(); - command.Connection = Connection; - await command.ExecuteNonQueryAsync(token); - } - } - - public static object ExecuteScalar(this SqlCommand command, string connection) - { - using (var Connection = new SqlConnection(connection)) - { - Connection.Open(); - command.Connection = Connection; - return command.ExecuteScalar(); - } - } - - public static T ExecuteScalar(this SqlCommand command, string connection) - { - using (var Connection = new SqlConnection(connection)) - { - Connection.Open(); - command.Connection = Connection; - return (T)command.ExecuteScalar(); - } - } - - public static DataTable ExecuteSelect(this SqlCommand command) - { - return command.ExecuteSelect(DefaultConnection); - } - - public static DataTable ExecuteSelect(this SqlCommand command, string connection) - { - using (var Connection = new SqlConnection(connection)) - { - Connection.Open(); - return command.ExecuteSelect(Connection); - } - } - - public static DataTable ExecuteSelect(this SqlCommand command, SqlConnection connection) - { - var Result = new DataTable { Locale = CultureInfo.CurrentCulture }; - command.Connection = connection; - using (var Reader = command.ExecuteReader()) - { - Result.Load(Reader); - } - return Result; - } - public static SqlCommand SetSchema(this SqlCommand command, string schema) { var name = command.CommandText.Split('.').Last(); diff --git a/FIAS.Core/Models/DownloadState.cs b/FIAS.Core/Models/DownloadState.cs index c79e688..25f3bb1 100644 --- a/FIAS.Core/Models/DownloadState.cs +++ b/FIAS.Core/Models/DownloadState.cs @@ -2,11 +2,6 @@ { public class DownloadState { - public DownloadState(float progress) - { - Progress = progress; - } - public DownloadState(long totalBytes, long downloadedBytes) { TotalBytes = totalBytes; diff --git a/FIAS.Core/Stores/FIASDatabaseStore.cs b/FIAS.Core/Stores/FIASDatabaseStore.cs index ca3bf2e..be4dc35 100644 --- a/FIAS.Core/Stores/FIASDatabaseStore.cs +++ b/FIAS.Core/Stores/FIASDatabaseStore.cs @@ -96,62 +96,61 @@ public List TablesInfo() private T UP_DatabasePropertyGet(string name) { - using (var Command = NewProcedure()) + using (var command = NewProcedure()) { - var P = Command.Parameters; + var P = command.Parameters; P.AddWithValue("@Name", name); - return Command.ExecuteScalar(Connection); + return Execute(command).Scalar(); } } private void UP_DatabasePropertySet(string name, object value) { - using (var Command = NewProcedure()) + using (var command = NewProcedure()) { - var P = Command.Parameters; + var P = command.Parameters; P.AddWithValue("@Name", name); P.AddWithValue("@Value", value); - Command.ExecuteNonQuery(Connection); + Execute(command).NonQuery(); } } private async Task UP_RefreshRegistry(FIASDivision division, CancellationToken token) { - using (var Command = NewProcedure()) + using (var command = NewProcedure()) { - Command.SetSchema($"{division}"); - Command.CommandTimeout = 0; - await Command.ExecuteNonQueryAsync(Connection, token); + command.SetSchema($"{division}"); + command.CommandTimeout = 0; + await Execute(command).NonQueryAsync(token); } } private object UP_TablePropertyGet(string table, string name) { - using (var Command = NewProcedure()) + using (var command = NewProcedure()) { - var P = Command.Parameters; + var P = command.Parameters; P.AddWithValue("@Table", table); P.AddWithValue("@Name", name); - return Command.ExecuteScalar(Connection); + return Execute(command).Scalar(); } } private void UP_TablePropertySet(string table, string name, object value) { - using (var Command = NewProcedure()) + using (var command = NewProcedure()) { - var P = Command.Parameters; - P.AddWithValue("@Table", table); - P.AddWithValue("@Name", name); - P.AddWithValue("@Value", value); - Command.ExecuteNonQuery(Connection); + command.AddParameter("@Table", table); + command.AddParameter("@Name", name); + command.AddParameter("@Value", value); + Execute(command).NonQuery(); } } private DataTable UP_TablesInfo() { - using (var Command = NewProcedure()) - return Command.ExecuteSelect(Connection); + using (var command = NewProcedure()) + return Execute(command).Select(); } #endregion SQL diff --git a/FIAS.Core/Stores/FIASStore.cs b/FIAS.Core/Stores/FIASStore.cs index ea18df3..658f245 100644 --- a/FIAS.Core/Stores/FIASStore.cs +++ b/FIAS.Core/Stores/FIASStore.cs @@ -2,7 +2,6 @@ using FIAS.Core.Models; using System.Collections.Generic; using System.Data; -using System.Data.SqlClient; using System.Linq; using System.Threading.Tasks; @@ -129,7 +128,7 @@ public async Task> Statistics() private DataTable UP_CB_Levels() { using (var command = NewProcedure()) - return command.ExecuteSelect(Connection); + return Execute(command).Select(); } private DataTable UP_FIAS_Statistics() @@ -137,36 +136,36 @@ private DataTable UP_FIAS_Statistics() using (var command = NewProcedure()) { command.CommandTimeout = 300; - return command.ExecuteSelect(Connection); + return Execute(command).Select(); } } - private DataTable UP_RegistryHierarchy(string GUID, FIASDivision H) + private long UP_IDByGUID(string GUID) { using (var command = NewProcedure()) { - command.SetSchema($"{H}"); command.AddParameter("@GUID", GUID); - return command.ExecuteSelect(Connection); + return Execute(command).Scalar(); } } - private long UP_IDByGUID(string GUID) + private DataTable UP_ObjectParameters(string GUID) { using (var command = NewProcedure()) { + command.CommandTimeout = 300; command.AddParameter("@GUID", GUID); - return command.ExecuteScalar(Connection); + return Execute(command).Select(); } } - private DataTable UP_ObjectParameters(string GUID) + private DataTable UP_RegistryHierarchy(string GUID, FIASDivision H) { using (var command = NewProcedure()) { - command.CommandTimeout = 300; + command.SetSchema($"{H}"); command.AddParameter("@GUID", GUID); - return command.ExecuteSelect(Connection); + return Execute(command).Select(); } } @@ -178,7 +177,7 @@ private DataTable UP_RegistrySelect(string GUID, FIASDivision H) { command.SetSchema($"{H}"); command.AddParameter("@GUID", GUID); - return command.ExecuteSelect(Connection); + return Execute(command).Select(); } } @@ -188,7 +187,7 @@ private DataTable UP_RegistrySelectChild(string GUID, FIASDivision H) { command.SetSchema($"{H}"); command.AddParameter("@GUID", GUID); - return command.ExecuteSelect(Connection); + return Execute(command).Select(); } } @@ -200,7 +199,7 @@ private DataTable UP_SearchRegistry(FIASDivision H, string Search, int? Level, i command.AddParameter("@Search", Search); command.AddParameter("@Level", Level); command.AddParameter("@Limit", Limit); - return command.ExecuteSelect(Connection); + return Execute(command).Select(); } } @@ -212,7 +211,7 @@ private DataTable UP_SearchRegistryByGUID(FIASDivision H, string GUID, int? Leve command.AddParameter("@GUID", GUID); command.AddParameter("@Level", Level); command.AddParameter("@Limit", Limit); - return command.ExecuteSelect(Connection); + return Execute(command).Select(); } } diff --git a/FIAS.Core/Stores/SQLCommandExecutor.cs b/FIAS.Core/Stores/SQLCommandExecutor.cs new file mode 100644 index 0000000..c6ce89e --- /dev/null +++ b/FIAS.Core/Stores/SQLCommandExecutor.cs @@ -0,0 +1,289 @@ +using System; +using System.Data; +using System.Data.SqlClient; +using System.Globalization; +using System.Threading; +using System.Threading.Tasks; + +namespace FIAS.Core +{ + public class SQLCommandExecutor + { + public SQLCommandExecutor(SqlCommand command, string connection) + { + Command = command; + Connection = connection; + } + + public SqlCommand Command { get; } + + public string Connection { get; set; } + + /// + /// https://dba.stackexchange.com/questions/9840/why-would-set-arithabort-on-dramatically-speed-up-a-query + /// https://dba.stackexchange.com/questions/2500/make-sqlclient-default-to-arithabort-on + /// + /// + private static void SetARITHABORT(SqlConnection connection) + { + SqlCommand ARITHABORT = new SqlCommand("SET ARITHABORT ON", connection); + ARITHABORT.ExecuteNonQuery(); + } + + #region NonQuery + + /// + /// Выполнить с соединением по умолчанию + /// + public void NonQuery() => NonQuery(Connection); + + /// + /// Выполнить с указанным соединением + /// + public void NonQuery(string connection) + { + using (var Connection = new SqlConnection(connection)) + { + Connection.Open(); + Command.Connection = Connection; + Command.ExecuteNonQuery(); + } + } + + /// + /// Выполнить асинхронно с соединением по умолчанию + /// + public async Task NonQueryAsync(CancellationToken token) => await NonQueryAsync(Connection, token); + + /// + /// Выполнить асинхронно с соединением по умолчанию + /// + public async Task NonQueryAsync() => await NonQueryAsync(Connection); + + /// + /// Выполнить асинхронно с указанным соединением + /// + public async Task NonQueryAsync(string connection, CancellationToken token) + { + using (var Connection = new SqlConnection(connection)) + { + Connection.Open(); + Command.Connection = Connection; + await Command.ExecuteNonQueryAsync(token); + } + } + + /// + /// Выполнить асинхронно с указанным соединением + /// + public async Task NonQueryAsync(string connection) + { + using (var Connection = new SqlConnection(connection)) + { + Connection.Open(); + Command.Connection = Connection; + await Command.ExecuteNonQueryAsync(); + } + } + + #endregion NonQuery + + #region Scalar + + public object Scalar() => Scalar(Connection); + + public object Scalar(string connection) + { + using (var Connection = new SqlConnection(connection)) + { + Connection.Open(); + Command.Connection = Connection; + return Command.ExecuteScalar(); + } + } + + public T Scalar() => Scalar(Connection); + + public T Scalar(string connection) + { + using (var Connection = new SqlConnection(connection)) + { + Connection.Open(); + Command.Connection = Connection; + return (T)Command.ExecuteScalar(); + } + } + + #endregion Scalar + + #region ScalarFunction + + public T ScalarFunction() => ScalarFunction(Connection); + + public T ScalarFunction(string connection) + { + var result = Command.Parameters.Add(new SqlParameter("@Result", default(T)) { Direction = ParameterDirection.ReturnValue }); + using (var Connection = new SqlConnection(connection)) + { + Connection.Open(); + Command.Connection = Connection; + Command.ExecuteNonQuery(); + if (result.Value == DBNull.Value) { return default; } + return (T)result.Value; + } + } + + #endregion ScalarFunction + + #region Select + + public DataTable Select() => Select(Connection); + + public DataTable Select(string connection) + { + using (var Connection = new SqlConnection(connection)) + { + Connection.Open(); + return Select(Connection); + } + } + + public Task SelectAsync() => SelectAsync(Connection); + + public async Task SelectAsync(string connection) + { + using (var Connection = new SqlConnection(connection)) + { + Connection.Open(); + return await SelectAsync(Connection); + } + } + + private DataTable Select(SqlConnection connection) + { + var Result = new DataTable { Locale = CultureInfo.CurrentCulture }; + Command.Connection = connection; + using (var Reader = Command.ExecuteReader()) + { + Result.Load(Reader); + } + return Result; + } + + private async Task SelectAsync(SqlConnection connection) + { + var Result = new DataTable { Locale = CultureInfo.CurrentCulture }; + Command.Connection = connection; + using (var Reader = await Command.ExecuteReaderAsync()) + { + await Task.Run(() => Result.Load(Reader)); + } + return Result; + } + + #endregion Select + + #region Select + + public T Select() where T : DataTable, new() => Select(Connection); + + public T Select(string connection) where T : DataTable, new() + { + using (var Connection = new SqlConnection(connection)) + { + Connection.Open(); + return Select(Connection); + } + } + + public Task SelectAsync() where T : DataTable, new() => SelectAsync(Connection); + + public async Task SelectAsync(string connection) where T : DataTable, new() + { + using (var Connection = new SqlConnection(connection)) + { + Connection.Open(); + return await SelectAsync(Connection); + } + } + + private T Select(SqlConnection connection) where T : DataTable, new() + { + var Result = new T { Locale = CultureInfo.CurrentCulture }; + Command.Connection = connection; + using (var Reader = Command.ExecuteReader()) + { + Result.Load(Reader); + } + return Result; + } + + private async Task SelectAsync(SqlConnection connection) where T : DataTable, new() + { + var Result = new T { Locale = CultureInfo.CurrentCulture }; + Command.Connection = connection; + using (var Reader = await Command.ExecuteReaderAsync()) + { + await Task.Run(() => Result.Load(Reader)); + } + return Result; + } + + #endregion Select + + #region SelectRow + + public TResult SelectRow(Func selector, SqlConnection connection) + { + using (var Result = Select(connection)) + { + var row = Result.Rows.Count > 0 ? Result.Rows[0] : null; + return selector(row); + } + } + + public DataRow SelectRow() => SelectRow(Connection); + + public DataRow SelectRow(string connection) + { + using (var Connection = new SqlConnection(connection)) + { + Connection.Open(); + return SelectRow(Connection); + } + } + + private DataRow SelectRow(SqlConnection connection) + { + //var Result = new DataTable { Locale = CultureInfo.CurrentCulture }; + //Command.Connection = connection; + //using (var Reader = Command.ExecuteReader()) + //{ + // Result.Load(Reader); + //} + var Result = Select(connection); + return Result.Rows.Count > 0 ? Result.Rows[0] : null; + } + + #endregion SelectRow + + #region Reader + + public SqlDataReader Reader() => Reader(Connection); + + public SqlDataReader Reader(string connection) + { + var Connection = new SqlConnection(connection); + Connection.Open(); + return Reader(Connection); + } + + private SqlDataReader Reader(SqlConnection connection) + { + Command.Connection = connection; + return Command.ExecuteReader(CommandBehavior.CloseConnection); + } + + #endregion Reader + } +} \ No newline at end of file diff --git a/FIAS.Core/Stores/SQLStore.cs b/FIAS.Core/Stores/SQLStore.cs index 7b5d4a3..4f99385 100644 --- a/FIAS.Core/Stores/SQLStore.cs +++ b/FIAS.Core/Stores/SQLStore.cs @@ -8,11 +8,26 @@ public abstract class SQLStore { protected SQLStore(string connection) => Connection = connection; + /// + /// Соединение по умолчанию + /// public string Connection { get; set; } + /// + /// Создаёт новую команду с именем вызывающего метода + /// + /// + /// protected static SqlCommand NewProcedure([CallerMemberName] string name = null) => new SqlCommand(name) { CommandType = CommandType.StoredProcedure }; + + /// + /// Создаёт новый экземпляр + /// + /// + /// + protected SQLCommandExecutor Execute(SqlCommand command) => new SQLCommandExecutor(command, Connection); } } \ No newline at end of file diff --git a/FIAS.Core/Stores/SubjectStore.cs b/FIAS.Core/Stores/SubjectStore.cs new file mode 100644 index 0000000..3770fbb --- /dev/null +++ b/FIAS.Core/Stores/SubjectStore.cs @@ -0,0 +1,110 @@ +using System.Collections.Generic; + +namespace FIAS.Core.Stores +{ + public class SubjectStore + { + /// + /// Справочник субъектов РФ + /// + /// + /// console.log(A.addresses.sort((s1,s2)=>{return s1.region_code-s2.region_code}).map(R=>`"{${parseInt(R.region_code)}","${R.full_name}"}`).join(`,\r\n`)) + /// + /// + public static Dictionary GetSubjects() + { + return new Dictionary() { + {"01", "Республика Адыгея (Адыгея)"}, + {"02", "Республика Башкортостан"}, + {"03", "Республика Бурятия"}, + {"04", "Республика Алтай"}, + {"05", "Республика Дагестан"}, + {"06", "Республика Ингушетия"}, + {"07", "Кабардино-Балкарская Республика"}, + {"08", "Республика Калмыкия"}, + {"09", "Карачаево-Черкесская Республика"}, + {"10", "Республика Карелия"}, + {"11", "Республика Коми"}, + {"12", "Республика Марий Эл"}, + {"13", "Республика Мордовия"}, + {"14", "Республика Саха (Якутия)"}, + {"15", "Республика Северная Осетия - Алания"}, + {"16", "Республика Татарстан (Татарстан)"}, + {"17", "Республика Тыва"}, + {"18", "Удмуртская Республика"}, + {"19", "Республика Хакасия"}, + {"20", "Чеченская Республика"}, + {"21", "Чувашская Республика - Чувашия"}, + {"22", "Алтайский край"}, + {"23", "Краснодарский край"}, + {"24", "Красноярский край"}, + {"25", "Приморский край"}, + {"26", "Ставропольский край"}, + {"27", "Хабаровский край"}, + {"28", "Амурская область"}, + {"29", "Архангельская область"}, + {"30", "Астраханская область"}, + {"31", "Белгородская область"}, + {"32", "Брянская область"}, + {"33", "Владимирская область"}, + {"34", "Волгоградская область"}, + {"35", "Вологодская область"}, + {"36", "Воронежская область"}, + {"37", "Ивановская область"}, + {"38", "Иркутская область"}, + {"39", "Калининградская область"}, + {"40", "Калужская область"}, + {"41", "Камчатский край"}, + {"42", "Кемеровская область - Кузбасс"}, + {"43", "Кировская область"}, + {"44", "Костромская область"}, + {"45", "Курганская область"}, + {"46", "Курская область"}, + {"47", "Ленинградская область"}, + {"48", "Липецкая область"}, + {"49", "Магаданская область"}, + {"50", "Московская область"}, + {"51", "Мурманская область"}, + {"52", "Нижегородская область"}, + {"53", "Новгородская область"}, + {"54", "Новосибирская область"}, + {"55", "Омская область"}, + {"56", "Оренбургская область"}, + {"57", "Орловская область"}, + {"58", "Пензенская область"}, + {"59", "Пермский край"}, + {"60", "Псковская область"}, + {"61", "Ростовская область"}, + {"62", "Рязанская область"}, + {"63", "Самарская область"}, + {"64", "Саратовская область"}, + {"65", "Сахалинская область"}, + {"66", "Свердловская область"}, + {"67", "Смоленская область"}, + {"68", "Тамбовская область"}, + {"69", "Тверская область"}, + {"70", "Томская область"}, + {"71", "Тульская область"}, + {"72", "Тюменская область"}, + {"73", "Ульяновская область"}, + {"74", "Челябинская область"}, + {"75", "Забайкальский край"}, + {"76", "Ярославская область"}, + {"77", "город Москва"}, + {"78", "город Санкт-Петербург"}, + {"79", "Еврейская автономная область"}, + {"83", "Ненецкий автономный округ"}, + {"86", "Ханты-Мансийский автономный округ - Югра"}, + {"87", "Чукотский автономный округ"}, + {"89", "Ямало-Ненецкий автономный округ"}, + {"90", "Запорожская область"}, + {"91", "Республика Крым"}, + {"92", "город Севастополь"}, + {"93", "Донецкая Народная Республика"}, + {"94", "Луганская Народная Республика"}, + {"95", "Херсонская область"}, + {"99", "город Байконур"} + }; + } + } +} \ No newline at end of file diff --git a/FIASUpdate/ArchiveDownloader.cs b/FIASUpdate/ArchiveDownloader.cs index 952c12b..8a140af 100644 --- a/FIASUpdate/ArchiveDownloader.cs +++ b/FIASUpdate/ArchiveDownloader.cs @@ -29,49 +29,15 @@ public ArchiveDownloader(int threads) Semaphore = new SemaphoreSlim(threads); } - public async Task Download(FIASArchive archive, CancellationToken token = default) + public async Task Download(FIASArchiveDelta archive, IProgress progress, CancellationToken token = default) { - var LocalFile = new FileInfo(archive.ArchivePath); + var file = new FileInfo(archive.ArchivePath); try { await Semaphore.WaitAsync().ConfigureAwait(false); token.ThrowIfCancellationRequested(); - Directory.CreateDirectory(LocalFile.DirectoryName); - using (var FS = new FileStream(LocalFile.FullName, FileMode.Create)) - await Client.DownloadAsync(archive.URLDelta, FS, token).ConfigureAwait(false); - } - finally - { - Semaphore.Release(); - } - } - - public async Task Download(FIASArchive archive, IProgress progress, CancellationToken token = default) - { - var LocalFile = new FileInfo(archive.ArchivePath); - try - { - await Semaphore.WaitAsync().ConfigureAwait(false); - token.ThrowIfCancellationRequested(); - Directory.CreateDirectory(LocalFile.DirectoryName); - using (var FS = new FileStream(LocalFile.FullName, FileMode.Create)) - await Client.DownloadAsync(archive.URLDelta, FS, progress, token).ConfigureAwait(false); - } - finally - { - Semaphore.Release(); - } - } - - public async Task Download(FIASArchive archive, IProgress progress, CancellationToken token = default) - { - var LocalFile = new FileInfo(archive.ArchivePath); - try - { - await Semaphore.WaitAsync().ConfigureAwait(false); - token.ThrowIfCancellationRequested(); - Directory.CreateDirectory(LocalFile.DirectoryName); - using (var FS = new FileStream(LocalFile.FullName, FileMode.Create)) + Directory.CreateDirectory(file.DirectoryName); + using (var FS = new FileStream(file.FullName, FileMode.Create)) await Client.DownloadAsync(archive.URLDelta, FS, progress, token).ConfigureAwait(false); } finally @@ -86,7 +52,7 @@ public async Task Download(FIASArchive archive, IProgress progres /// /// /// - public async Task GetArchiveSize(FIASArchive archive, CancellationToken token = default) + public async Task GetArchiveSize(FIASArchiveDelta archive, CancellationToken token = default) { try { diff --git a/FIASUpdate/Models/DBStringLVI.cs b/FIASUpdate/Controls/DBStringLVI.cs similarity index 94% rename from FIASUpdate/Models/DBStringLVI.cs rename to FIASUpdate/Controls/DBStringLVI.cs index 74a9356..aa993fa 100644 --- a/FIASUpdate/Models/DBStringLVI.cs +++ b/FIASUpdate/Controls/DBStringLVI.cs @@ -1,7 +1,7 @@ using System.Data.SqlClient; using System.Windows.Forms; -namespace FIASUpdate.Models +namespace FIASUpdate.Controls { internal class DBStringLVI : ListViewItem { diff --git a/FIASUpdate/Controls/TextBoxFileDrop.cs b/FIASUpdate/Controls/TextBoxFileDrop.cs new file mode 100644 index 0000000..134ca1f --- /dev/null +++ b/FIASUpdate/Controls/TextBoxFileDrop.cs @@ -0,0 +1,57 @@ +using System.ComponentModel; +using System.IO; +using System.Windows.Forms; + +namespace FIASUpdate.Controls +{ + public class TextBoxFileDrop : TextBox + { + public TextBoxFileDrop() + { + base.ReadOnly = true; + AllowDrop = true; + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [DefaultValue(true)] + public new bool ReadOnly { get; } = true; + + /// + /// Открыть окно выбора файла + /// + public void SelectFile() + { + var F = new OpenFileDialog { InitialDirectory = Text }; + if (F.ShowDialog() == DialogResult.OK) { Text = F.FileName; } + } + + private static bool IsValid(string file) + { + return file.EndsWith(".zip") && File.Exists(file); + } + + protected override void OnDragDrop(DragEventArgs e) + { + if (e.Data is null) { return; } + var file = ((string[])e.Data.GetData(DataFormats.FileDrop))[0]; + if (IsValid(file)) { Text = file; } + OnTextChanged(new System.EventArgs()); + } + + protected override void OnDragEnter(DragEventArgs e) => ProcessDrag(e); + + protected override void OnDragOver(DragEventArgs e) => ProcessDrag(e); + + private static void ProcessDrag(DragEventArgs e) + { + var Effect = DragDropEffects.None; + if (e.Data is null) { return; } + if (e.Data.GetDataPresent(DataFormats.FileDrop)) + { + var file = ((string[])e.Data.GetData(DataFormats.FileDrop))[0]; + if (IsValid(file)) { Effect = DragDropEffects.Link; } + } + e.Effect = Effect; + } + } +} \ No newline at end of file diff --git a/FIASUpdate/Database/DBImport.cs b/FIASUpdate/Database/DBImport.cs index 7535060..d2e1daa 100644 --- a/FIASUpdate/Database/DBImport.cs +++ b/FIASUpdate/Database/DBImport.cs @@ -1,6 +1,9 @@ using FIAS.Core.Stores; using FIASUpdate.Models; +using FIASUpdate.Readers; using JANL; +using Microsoft.Data.SqlClient; +using Microsoft.SqlServer.Management.Smo; using System; using System.Collections.Generic; using System.IO; @@ -9,11 +12,16 @@ namespace FIASUpdate { - internal abstract class DBImport : DBClient + /// + /// Базовый класс для импорта архива + /// + /// Тип архива + internal abstract class DBImport : DBClient where T : FIASArchive { protected readonly SyncEvent Events; protected readonly FIASDatabaseStore Store = new FIASDatabaseStore(FIASProperties.SQLConnection); protected readonly List Tables = new List(); + protected T Archive; protected IProgress SP; protected CancellationToken Token; @@ -22,44 +30,94 @@ protected DBImport() Events = new SyncEvent(this); } - protected abstract string ScanPath { get; } + /// + /// Список кодов субъектов РФ + /// + public IEnumerable Subjects { get; set; } + + /// + /// Путь к папке с файлами ФИАС + /// + protected string ScanPath => Archive.ExtractPath; public void Import() => Import(default, default); public void Import(IProgress progress) => Import(progress, default); - public abstract void Import(IProgress progress, CancellationToken token); + public virtual void Import(IProgress progress, CancellationToken token) + { + SP = progress; + Token = token; + } + + /// + /// Распаковывает архив + /// + protected void Extract() + { + SP?.Report(new TaskProgress($"Распаковка архива", 0, 0)); + Archive.Extract(Subjects); + } + + /// + /// Импортировать в данные из в таблицу + /// + /// Таблица БД + /// Таблица FIAS + protected virtual void ImportTable(Table target, FIASTable source) + { + using (var connection = NewConnection(DBName)) + using (var SBC = new SqlBulkCopy(connection) { DestinationTableName = target.Name, BulkCopyTimeout = 0, NotifyAfter = 100 }) + { + SBC.SqlRowsCopied += SBC_SqlRowsCopied; + SBC.EnableStreaming = true; + var names = target.Columns.Cast().Select(C => C.Name); + foreach (var file in source.Files) + { + Token.ThrowIfCancellationRequested(); + SP?.Report(new TaskProgress($"Импорт файла: {file.FullName}", 0, 0)); + using (var FR = new FIASReader(file.Path, names)) + { + SBC.WriteToServer(FR); + } + SBC.NotifyAfter = 100; + var count = SBC.RowsCopied; + SP?.Report(new TaskProgress($"Импорт файла завершён: {file.FullName}", count, count)); + Thread.Sleep(200); + } + } + } /// /// Поиск файлов для импорта /// protected void ScanFiles() { - Tables.Clear(); + // Корневые файлы var rootFiles = Directory.EnumerateFiles(ScanPath, "*.xml") .Select(F => new FIASFile(F)); - + // Файлы субъектов var subjectFiles = Directory.EnumerateDirectories(ScanPath) .SelectMany(D => Directory.EnumerateFiles(D)) .Select(F => new FIASFile(F) { Region = Path.GetFileName(Path.GetDirectoryName(F)) }); - + // Параметры объединены в одну таблицу var tables = Enumerable.Concat(rootFiles, subjectFiles) .ToLookup(F => F.Name.Contains("PARAMS") ? "PARAMS" : F.Name) .Select(L => new FIASTable(L.Key, L.ToList())); + Tables.Clear(); Tables.AddRange(tables); } - protected void ShrinkDatabase() + private void SBC_SqlRowsCopied(object sender, SqlRowsCopiedEventArgs e) { - var Size = DB.Size; - SP?.Report(new TaskProgress($"Сжатие БД ({Size:N2} МБ)", 0, 0)); - Thread.Sleep(500); - Shrink(); - SP?.Report(new TaskProgress($"БД сжата ({Size:N2} МБ -> {DB.Size:N2} МБ)")); + SqlBulkCopy SBC = (SqlBulkCopy)sender; + var SBCCount = (int)e.RowsCopied; + SP?.Report(new TaskProgress(SBCCount, SBCCount)); + if (SBCCount >= 10000 && SBC.NotifyAfter != 1000) { SBC.NotifyAfter = 1000; } } } } \ No newline at end of file diff --git a/FIASUpdate/Database/DBImportDelta.cs b/FIASUpdate/Database/DBImportDelta.cs index ff29f88..827fcdf 100644 --- a/FIASUpdate/Database/DBImportDelta.cs +++ b/FIASUpdate/Database/DBImportDelta.cs @@ -1,7 +1,5 @@ using FIASUpdate.Models; -using FIASUpdate.Readers; using JANL; -using Microsoft.Data.SqlClient; using Microsoft.SqlServer.Management.Smo; using System; using System.Linq; @@ -10,59 +8,33 @@ namespace FIASUpdate { - internal class DBImportDelta : DBImport + /// + /// Класс для импорта дельта архива + /// + internal class DBImportDelta : DBImport { - private readonly FIASArchive Archive; - private readonly ImportDeltaOptions Options; - - public DBImportDelta(FIASArchive archive, ImportDeltaOptions options) + public DBImportDelta(FIASArchiveDelta archive) { - Options = options; Archive = archive; } public override void Import(IProgress progress, CancellationToken token) { - SP = progress; - Token = token; + base.Import(progress, token); Extract(); ScanFiles(); - foreach (var item in Tables) - { - // Проверка существования - var table = DB.Tables[item.Name]; - if (table == null) { continue; } - // Проверка настроек импорта - table.Refresh(); - if (!Store.GetCanImport(table.Name)) { continue; } - - // Импорт - ImportTable(table, item); - Store.SetLastImport(item.Name, item.Date); - Thread.Sleep(500); - } - Store.SetVersion(Archive.Date); - if (Options.ShrinkDatabase) { ShrinkDatabase(); } - } - - private void Extract() - { - SP.Report(new TaskProgress($"Распаковка архива", 0, 0)); - Archive.Extract(Options.Subjects); + ImportTables(); } #region Table Import - protected override string ScanPath => Archive.ExtractPath; - /// /// /// /// Таблица БД /// Таблица FIAS - /// Количество импортированных строк - private long ImportTable(Table target, FIASTable source) + protected override void ImportTable(Table target, FIASTable source) { // Создать временную таблицу var temporaryName = $"_{target.Name}"; @@ -74,58 +46,48 @@ private long ImportTable(Table target, FIASTable source) temporaryTable.Create(); // Импортировать данные во временную таблицу - var columns = target.Columns.Cast(); - using (var connection = NewConnection(DBName)) - using (var SBC = new SqlBulkCopy(connection) { DestinationTableName = temporaryTable.Name, BulkCopyTimeout = 0, NotifyAfter = 100 }) - { - SBC.SqlRowsCopied += SBC_SqlRowsCopied; - SBC.EnableStreaming = true; - var names = target.Columns.Cast().Select(C => C.Name); - foreach (var File in source.Files) - { - Token.ThrowIfCancellationRequested(); - SP?.Report(new TaskProgress($"Импорт файла: {File.FullName}", 0, 0)); - using (var FR = new FIASReader(File.Path, names)) - { - SBC.WriteToServer(FR); - } - SBC.NotifyAfter = 100; - var Count = SBC.RowsCopied; - SP.Report(new TaskProgress($"Импорт файла завершён: {File.FullName}", Count, Count)); - Thread.Sleep(200); - } - } + base.ImportTable(temporaryTable, source); - SP.Report(new TaskProgress($"Объединение таблиц: {target.Name}", 0, 0)); + SP?.Report(new TaskProgress($"Объединение таблиц: {target.Name}", 0, 0)); // Объединить таблицы + var columns = target.Columns.Cast(); var key = columns.First().Name; var insert = columns.Select(C => $"[{C.Name}]"); var values = columns.Select(C => $"[S].[{C.Name}]"); var update = columns.Skip(1).Select(C => $"[{C.Name}] = [S].[{C.Name}]"); - var query = new StringBuilder(); - query.AppendLine($"MERGE INTO [{target.Name}] AS [T]"); - query.AppendLine($"USING [{temporaryName}] AS [S]"); - query.AppendLine($"ON([T].[{key}] = [S].[{key}])"); - query.AppendLine("WHEN NOT MATCHED BY TARGET THEN"); - query.AppendLine($"INSERT ({string.Join(",", insert)})"); - query.AppendLine($"VALUES ({string.Join(",", values)})"); - query.AppendLine("WHEN MATCHED THEN"); - query.AppendLine($"UPDATE SET { string.Join(",", update)};"); + var query = new StringBuilder() + .AppendLine($"MERGE INTO [{target.Name}] AS [T]") + .AppendLine($"USING [{temporaryName}] AS [S]") + .AppendLine($"ON([T].[{key}] = [S].[{key}])") + .AppendLine("WHEN NOT MATCHED BY TARGET THEN") + .AppendLine($"INSERT ({string.Join(",", insert)})") + .AppendLine($"VALUES ({string.Join(",", values)})") + .AppendLine("WHEN MATCHED THEN") + .AppendLine($"UPDATE SET {string.Join(",", update)};"); DB.ExecuteNonQuery(query.ToString()); temporaryTable.Drop(); - SP.Report(new TaskProgress($"Импорт в таблицу завершён: {target.Name}", 0, 0)); - target.Refresh(); - return target.RowCount; } - private void SBC_SqlRowsCopied(object sender, SqlRowsCopiedEventArgs e) + private void ImportTables() { - SqlBulkCopy SBC = (SqlBulkCopy)sender; - var SBCCount = (int)e.RowsCopied; - SP.Report(new TaskProgress(SBCCount, SBCCount)); - if (SBCCount >= 10000 && SBC.NotifyAfter != 1000) { SBC.NotifyAfter = 1000; } + foreach (var table in Tables) + { + // Проверка существования + var T = DB.Tables[table.Name]; + if (T == null) { continue; } + // Проверка настроек импорта + T.Refresh(); + if (!Store.GetCanImport(T.Name)) { continue; } + + // Импорт + ImportTable(T, table); + SP?.Report(new TaskProgress($"Импорт в таблицу завершён: {T.Name}", 0, 0)); + Store.SetLastImport(table.Name, table.Date); + Thread.Sleep(500); + } + Store.SetVersion(Archive.Date); } #endregion Table Import diff --git a/FIASUpdate/Database/DBImportFull.cs b/FIASUpdate/Database/DBImportFull.cs index 15b49af..8d7f05d 100644 --- a/FIASUpdate/Database/DBImportFull.cs +++ b/FIASUpdate/Database/DBImportFull.cs @@ -1,145 +1,92 @@ using FIASUpdate.Models; -using FIASUpdate.Readers; using JANL; -using Microsoft.Data.SqlClient; using Microsoft.SqlServer.Management.Smo; using System; using System.Collections.Generic; -using System.Data; -using System.IO; -using System.Linq; using System.Threading; namespace FIASUpdate { - internal class DBImportFull : DBImport + /// + /// Класс для импорта полного архива + /// + internal class DBImportFull : DBImport { - private readonly Dictionary _result = new Dictionary(); - private readonly ImportFullOptions Options; + private readonly List _result = new List(); - public DBImportFull() : this(new ImportFullOptions { OnlyEmpty = true }) { } - - public DBImportFull(ImportFullOptions options) + public DBImportFull(FIASArchiveFull archive) { - Options = options; + Archive = archive; } - public IReadOnlyDictionary Result => _result; - private static string GAR_Version => $@"{FIASProperties.GAR_Full}\version.txt"; + /// + /// Импортировать только в пустые таблицы + /// + public bool OnlyEmpty { get; set; } + + /// + /// Результат импорта таблиц + /// + public IReadOnlyList Result => _result; public override void Import(IProgress progress, CancellationToken token) { - SP = progress; - Token = token; + base.Import(progress, token); - _result.Clear(); + Archive.ExtractVersion(); + Extract(); ScanFiles(); ImportTables(); - if (Options.ShrinkDatabase) { ShrinkDatabase(); } } private void AddResult(string table, string status) { - _result.Add(table, status); - OnResultAdded(new ResultAddedEventArgs(table, status)); + var result = new TableImportResult(table, status); + _result.Add(result); + OnResultAdded(new ResultAddedEventArgs(result)); } #region Table Import - protected override string ScanPath => FIASProperties.GAR_Full; - - /// - /// - /// - /// Таблица БД - /// Таблица FIAS - /// Количество импортированных строк - private long ImportTable(Table target, FIASTable source) - { - using (var Connection = NewConnection(DBName)) - using (var SBC = new SqlBulkCopy(Connection) { DestinationTableName = target.Name, BulkCopyTimeout = 0, NotifyAfter = 100 }) - { - SBC.SqlRowsCopied += SBC_SqlRowsCopied; - SBC.EnableStreaming = true; - var names = target.Columns.Cast().Select(C => C.Name); - foreach (var File in source.Files) - { - Token.ThrowIfCancellationRequested(); - SP?.Report(new TaskProgress($"Импорт файла: {File.FullName}", 0, 0)); - using (var FR = new FIASReader(File.Path, names)) - { - SBC.WriteToServer(FR); - } - SBC.NotifyAfter = 100; - var Count = SBC.RowsCopied; - SP?.Report(new TaskProgress($"Импорт файла завершён: {File.FullName}", Count, Count)); - Thread.Sleep(1000); - } - SP?.Report(new TaskProgress($"Импорт в таблицу завершён: {target.Name}", 0, 0)); - target.Refresh(); - return target.RowCount; - } - } - private void ImportTables() { - var subjects = Tables - .SelectMany(T => T.Files.Where(F => !string.IsNullOrEmpty(F.Region)).Select(F => F.Region)) - .Distinct().ToList(); - DateTime date = new DateTime(2000, 1, 1); - if (File.Exists(GAR_Version)) - { - var V = File.ReadAllLines(GAR_Version); - DateTime.TryParse(V[0], out date); - } -#if false - Store.SetSubjects(subjects); - Store.SetVersion(date); -#endif - - foreach (var Table in Tables) + _result.Clear(); + foreach (var table in Tables) { // Проверка существования - Table T = DB.Tables[Table.Name]; + Table T = DB.Tables[table.Name]; if (T == null) { - AddResult(Table.Name, "Таблицы нет в БД"); + AddResult(table.Name, "Таблицы нет в БД"); continue; } // Проверка настроек импорта T.Refresh(); - if (!Store.GetCanImport(Table.Name)) + if (!Store.GetCanImport(table.Name)) { - AddResult(Table.Name, $"Пропущена ({T.RowCount:N0})"); + AddResult(table.Name, $"Пропущена ({T.RowCount:N0})"); continue; } - if (!Options.OnlyEmpty) + if (OnlyEmpty && T.RowCount > 0) { - T.TruncateData(); + AddResult(table.Name, $"Пропущена ({T.RowCount:N0})"); + continue; } - else if (T.RowCount > 0) + else { - AddResult(Table.Name, $"Пропущена ({T.RowCount:N0})"); - continue; + T.TruncateData(); } + // Импорт + ImportTable(T, table); + SP?.Report(new TaskProgress($"Импорт в таблицу завершён: {T.Name}", 0, 0)); + T.Refresh(); + Store.SetLastImport(table.Name, table.Date); - //Импорт - var Count = ImportTable(T, Table); - Store.SetLastImport(Table.Name, Table.Date); - AddResult(Table.Name, $"Импортирована ({Count:N0})"); - Thread.Sleep(2 * 1000); + var count = T.RowCount; + AddResult(table.Name, $"Импортирована ({count:N0})"); + Thread.Sleep(1000); } - - Store.SetSubjects(subjects); - Store.SetVersion(date); - } - - private void SBC_SqlRowsCopied(object sender, SqlRowsCopiedEventArgs e) - { - SqlBulkCopy SBC = (SqlBulkCopy)sender; - var SBCCount = (int)e.RowsCopied; - SP?.Report(new TaskProgress(SBCCount, SBCCount)); - if (SBCCount >= 10000 && SBC.NotifyAfter != 1000) { SBC.NotifyAfter = 1000; } + Store.SetVersion(Archive.Date); } #endregion Table Import @@ -152,15 +99,30 @@ private void SBC_SqlRowsCopied(object sender, SqlRowsCopiedEventArgs e) #endregion Events } + /// + /// + /// internal class ResultAddedEventArgs : EventArgs { - public ResultAddedEventArgs(string table, string status) + public ResultAddedEventArgs(TableImportResult result) + { + Result = result; + } + + public TableImportResult Result { get; } + } + /// + /// Результат импорта таблицы + /// + internal class TableImportResult + { + public TableImportResult(string table, string status) { Table = table; Status = status; } - public string Status { get; private set; } - public string Table { get; private set; } + public string Status { get; } + public string Table { get; } } } \ No newline at end of file diff --git a/FIASUpdate/Extensions/DataExtensions.cs b/FIASUpdate/Extensions/DataExtensions.cs index 8705dd5..140e732 100644 --- a/FIASUpdate/Extensions/DataExtensions.cs +++ b/FIASUpdate/Extensions/DataExtensions.cs @@ -1,7 +1,4 @@ using Microsoft.SqlServer.Management.Smo; -using System.Collections.Generic; -using System.Data; -using System.Linq; namespace FIASUpdate { diff --git a/FIASUpdate/Extensions/StringExtensions.cs b/FIASUpdate/Extensions/StringExtensions.cs deleted file mode 100644 index 82a3cf0..0000000 --- a/FIASUpdate/Extensions/StringExtensions.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace FIASUpdate -{ - internal static class StringExtensions - { - public static string TrimSpaces(this string str) - { - str = str.Trim(); - while (str.Contains(" ")) - { - str = str.Replace(" ", " "); - } - return str; - } - } -} \ No newline at end of file diff --git a/FIASUpdate/FIASUpdate.csproj b/FIASUpdate/FIASUpdate.csproj index bfd69c5..f665e35 100644 --- a/FIASUpdate/FIASUpdate.csproj +++ b/FIASUpdate/FIASUpdate.csproj @@ -374,6 +374,9 @@ + + Component + Component @@ -388,7 +391,6 @@ - Form @@ -401,13 +403,20 @@ FormOperation.cs + + Form + + + FormSubjectList.cs + Form FormSettings.cs - + + Form @@ -432,8 +441,8 @@ True icons8.resx - - + + @@ -489,6 +498,9 @@ FormOperation.cs + + FormSubjectList.cs + FormSettings.cs diff --git a/FIASUpdate/Forms/FormDBList.cs b/FIASUpdate/Forms/FormDBList.cs index 0b5d60e..05dbc44 100644 --- a/FIASUpdate/Forms/FormDBList.cs +++ b/FIASUpdate/Forms/FormDBList.cs @@ -1,4 +1,4 @@ -using FIASUpdate.Models; +using FIASUpdate.Controls; using FIASUpdate.Properties; using JANL.Extensions; using Microsoft.Data.ConnectionUI; diff --git a/FIASUpdate/Forms/FormImportDelta.Designer.cs b/FIASUpdate/Forms/FormImportDelta.Designer.cs index d05c366..40a8940 100644 --- a/FIASUpdate/Forms/FormImportDelta.Designer.cs +++ b/FIASUpdate/Forms/FormImportDelta.Designer.cs @@ -31,14 +31,14 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { this.label1 = new System.Windows.Forms.Label(); - this.statusStrip1 = new System.Windows.Forms.StatusStrip(); + this.Status = new System.Windows.Forms.StatusStrip(); this.TS_Progress = new FIASUpdate.Controls.ToolStripTaskProgress(); this.TS_Stopwatch = new JANL.Controls.ToolStripStopwatch(); this.LV_Archives = new System.Windows.Forms.ListView(); this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.сolumnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.B_Download = new System.Windows.Forms.Button(); this.B_Cancel = new System.Windows.Forms.Button(); this.B_Import = new System.Windows.Forms.Button(); @@ -47,7 +47,7 @@ private void InitializeComponent() this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); this.B_Open = new System.Windows.Forms.Button(); this.Info = new FIASUpdate.Controls.UC_DatabaseInfo(); - this.statusStrip1.SuspendLayout(); + this.Status.SuspendLayout(); this.FLP_Action.SuspendLayout(); this.groupBox1.SuspendLayout(); this.tableLayoutPanel2.SuspendLayout(); @@ -58,30 +58,30 @@ private void InitializeComponent() this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.label1.AutoSize = true; this.label1.Font = new System.Drawing.Font("Comic Sans MS", 72F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.label1.Location = new System.Drawing.Point(362, 345); + this.label1.Location = new System.Drawing.Point(284, 327); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(278, 135); this.label1.TabIndex = 0; this.label1.Text = "OwO"; // - // statusStrip1 + // Status // - this.statusStrip1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.statusStrip1.GripStyle = System.Windows.Forms.ToolStripGripStyle.Visible; - this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.Status.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.Status.GripStyle = System.Windows.Forms.ToolStripGripStyle.Visible; + this.Status.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.TS_Progress, this.TS_Stopwatch}); - this.statusStrip1.Location = new System.Drawing.Point(0, 458); - this.statusStrip1.Name = "statusStrip1"; - this.statusStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional; - this.statusStrip1.Size = new System.Drawing.Size(562, 22); - this.statusStrip1.TabIndex = 16; - this.statusStrip1.Text = "statusStrip1"; + this.Status.Location = new System.Drawing.Point(0, 440); + this.Status.Name = "Status"; + this.Status.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional; + this.Status.Size = new System.Drawing.Size(484, 22); + this.Status.TabIndex = 16; + this.Status.Text = "statusStrip1"; // // TS_Progress // this.TS_Progress.Name = "TS_Progress"; - this.TS_Progress.Size = new System.Drawing.Size(489, 17); + this.TS_Progress.Size = new System.Drawing.Size(411, 17); this.TS_Progress.Spring = true; this.TS_Progress.Status = "-"; this.TS_Progress.Text = "Статус: - -"; @@ -110,7 +110,7 @@ private void InitializeComponent() this.LV_Archives.Location = new System.Drawing.Point(3, 18); this.LV_Archives.MultiSelect = false; this.LV_Archives.Name = "LV_Archives"; - this.LV_Archives.Size = new System.Drawing.Size(556, 344); + this.LV_Archives.Size = new System.Drawing.Size(478, 332); this.LV_Archives.TabIndex = 17; this.LV_Archives.UseCompatibleStateImageBehavior = false; this.LV_Archives.View = System.Windows.Forms.View.Details; @@ -124,16 +124,16 @@ private void InitializeComponent() this.columnHeader2.Text = "Описание"; this.columnHeader2.Width = 91; // - // columnHeader3 - // - this.columnHeader3.Text = "Статус"; - this.columnHeader3.Width = 200; - // // сolumnHeader4 // this.сolumnHeader4.Text = "Размер"; this.сolumnHeader4.Width = 80; // + // columnHeader3 + // + this.columnHeader3.Text = "Статус"; + this.columnHeader3.Width = 200; + // // B_Download // this.B_Download.AutoSize = true; @@ -189,7 +189,8 @@ private void InitializeComponent() this.FLP_Action.Controls.Add(this.B_Download); this.FLP_Action.Controls.Add(this.B_Import); this.FLP_Action.Controls.Add(this.B_Cancel); - this.FLP_Action.Location = new System.Drawing.Point(224, 3); + this.FLP_Action.Location = new System.Drawing.Point(149, 0); + this.FLP_Action.Margin = new System.Windows.Forms.Padding(0); this.FLP_Action.Name = "FLP_Action"; this.FLP_Action.Size = new System.Drawing.Size(335, 31); this.FLP_Action.TabIndex = 21; @@ -201,7 +202,7 @@ private void InitializeComponent() this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; this.groupBox1.Location = new System.Drawing.Point(0, 56); this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(562, 365); + this.groupBox1.Size = new System.Drawing.Size(484, 353); this.groupBox1.TabIndex = 22; this.groupBox1.TabStop = false; this.groupBox1.Text = "Список архивов"; @@ -216,11 +217,11 @@ private void InitializeComponent() this.tableLayoutPanel2.Controls.Add(this.FLP_Action, 1, 0); this.tableLayoutPanel2.Controls.Add(this.B_Open, 0, 0); this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Bottom; - this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 421); + this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 409); this.tableLayoutPanel2.Name = "tableLayoutPanel2"; this.tableLayoutPanel2.RowCount = 1; this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel2.Size = new System.Drawing.Size(562, 37); + this.tableLayoutPanel2.Size = new System.Drawing.Size(484, 31); this.tableLayoutPanel2.TabIndex = 23; // // B_Open @@ -229,7 +230,7 @@ private void InitializeComponent() this.B_Open.AutoSize = true; this.B_Open.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.B_Open.Image = global::FIASUpdate.icons8.OpenedFolder16; - this.B_Open.Location = new System.Drawing.Point(3, 6); + this.B_Open.Location = new System.Drawing.Point(3, 3); this.B_Open.Name = "B_Open"; this.B_Open.Padding = new System.Windows.Forms.Padding(1); this.B_Open.Size = new System.Drawing.Size(115, 25); @@ -245,7 +246,7 @@ private void InitializeComponent() this.Info.Dock = System.Windows.Forms.DockStyle.Top; this.Info.Location = new System.Drawing.Point(0, 0); this.Info.Name = "Info"; - this.Info.Size = new System.Drawing.Size(562, 56); + this.Info.Size = new System.Drawing.Size(484, 56); this.Info.Subjects = null; this.Info.TabIndex = 18; this.Info.Version = new System.DateTime(((long)(0))); @@ -255,24 +256,25 @@ private void InitializeComponent() this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = global::FIASUpdate.Properties.Settings.Default.DefaultBackColor; - this.ClientSize = new System.Drawing.Size(562, 480); + this.ClientSize = new System.Drawing.Size(484, 462); this.Controls.Add(this.groupBox1); this.Controls.Add(this.Info); this.Controls.Add(this.tableLayoutPanel2); - this.Controls.Add(this.statusStrip1); + this.Controls.Add(this.Status); this.Controls.Add(this.label1); this.DataBindings.Add(new System.Windows.Forms.Binding("Font", global::FIASUpdate.Properties.Settings.Default, "DefaultFont", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); this.DataBindings.Add(new System.Windows.Forms.Binding("ForeColor", global::FIASUpdate.Properties.Settings.Default, "DefaultForeColor", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); this.DataBindings.Add(new System.Windows.Forms.Binding("BackColor", global::FIASUpdate.Properties.Settings.Default, "DefaultBackColor", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); this.Font = global::FIASUpdate.Properties.Settings.Default.DefaultFont; this.ForeColor = global::FIASUpdate.Properties.Settings.Default.DefaultForeColor; + this.MinimumSize = new System.Drawing.Size(500, 500); this.Name = "FormImportDelta"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Импорт БД"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormImportDelta_FormClosing); this.Load += new System.EventHandler(this.FormImportDelta_Load); - this.statusStrip1.ResumeLayout(false); - this.statusStrip1.PerformLayout(); + this.Status.ResumeLayout(false); + this.Status.PerformLayout(); this.FLP_Action.ResumeLayout(false); this.FLP_Action.PerformLayout(); this.groupBox1.ResumeLayout(false); @@ -286,7 +288,7 @@ private void InitializeComponent() #endregion private System.Windows.Forms.Label label1; - private System.Windows.Forms.StatusStrip statusStrip1; + private System.Windows.Forms.StatusStrip Status; private System.Windows.Forms.ListView LV_Archives; private System.Windows.Forms.ColumnHeader columnHeader1; private System.Windows.Forms.ColumnHeader columnHeader2; diff --git a/FIASUpdate/Forms/FormImportDelta.cs b/FIASUpdate/Forms/FormImportDelta.cs index 2ec2efc..01d5b86 100644 --- a/FIASUpdate/Forms/FormImportDelta.cs +++ b/FIASUpdate/Forms/FormImportDelta.cs @@ -22,7 +22,7 @@ public partial class FormImportDelta : Form private static readonly FIASClient Client = new FIASClient(); private static readonly Settings Settings = Settings.Default; private readonly FIASDatabaseStore Store = new FIASDatabaseStore(Settings.SQLConnection); - private List Archives; + private List Archives; private CancellationTokenSource CTS; private List Subjects; private DateTime Version; @@ -64,7 +64,7 @@ private async Task RefreshDatabase() // Бывают выгрузки без ссылок на архивы ГАР. // Если отсутствуют обе,то пропустить такую выгрузку, например от 24.11.2023. Archives = info.Where(I => !(string.IsNullOrEmpty(I.GarXMLFullURL) && string.IsNullOrEmpty(I.GarXMLDeltaURL))) - .Select(I => new FIASArchive(I)) + .Select(I => new FIASArchiveDelta(I)) .ToList(); } catch (SocketException ex) @@ -141,7 +141,7 @@ private async Task TaskDownload(CancellationToken token) var tasks = items.Select(async item => { var size = await AD.GetArchiveSize(item.Archive); - item.Archive.ArchiveSize = size; + item.Size = size; item.Refresh(); }); await Task.WhenAll(tasks); @@ -181,11 +181,10 @@ private async Task TaskImport(CancellationToken token) foreach (var item in items) { item.State = "Импорт данных"; - var Options = new ImportDeltaOptions + using (var FIAS = new DBImportDelta(item.Archive) { Subjects = Subjects - }; - using (var FIAS = new DBImportDelta(item.Archive, Options)) + }) { await Task.Run(() => FIAS.Import(TS_Progress.Progress, token)); } diff --git a/FIASUpdate/Forms/FormImportDelta.resx b/FIASUpdate/Forms/FormImportDelta.resx index 174ebc7..441d946 100644 --- a/FIASUpdate/Forms/FormImportDelta.resx +++ b/FIASUpdate/Forms/FormImportDelta.resx @@ -117,7 +117,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + 17, 17 \ No newline at end of file diff --git a/FIASUpdate/Forms/FormImportFull.Designer.cs b/FIASUpdate/Forms/FormImportFull.Designer.cs index f152ea5..5e8c22b 100644 --- a/FIASUpdate/Forms/FormImportFull.Designer.cs +++ b/FIASUpdate/Forms/FormImportFull.Designer.cs @@ -37,31 +37,36 @@ private void InitializeComponent() this.Result = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); this.B_Open = new System.Windows.Forms.Button(); - this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel(); + this.FLP_Action = new System.Windows.Forms.FlowLayoutPanel(); this.B_Import = new System.Windows.Forms.Button(); this.B_Cancel = new System.Windows.Forms.Button(); this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); this.CB_OnlyEmpty = new System.Windows.Forms.CheckBox(); - this.CB_Shrink = new System.Windows.Forms.CheckBox(); - this.statusStrip1 = new System.Windows.Forms.StatusStrip(); + this.B_Select = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.TB_Archive = new FIASUpdate.Controls.TextBoxFileDrop(); + this.label1 = new System.Windows.Forms.Label(); + this.TB_Version = new System.Windows.Forms.TextBox(); + this.Status = new System.Windows.Forms.StatusStrip(); this.TS_Progress = new FIASUpdate.Controls.ToolStripTaskProgress(); this.TS_Stopwatch = new JANL.Controls.ToolStripStopwatch(); + this.Info = new FIASUpdate.Controls.UC_DatabaseInfo(); this.groupBox2.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); - this.flowLayoutPanel2.SuspendLayout(); + this.FLP_Action.SuspendLayout(); this.groupBox1.SuspendLayout(); - this.flowLayoutPanel1.SuspendLayout(); - this.statusStrip1.SuspendLayout(); + this.tableLayoutPanel2.SuspendLayout(); + this.Status.SuspendLayout(); this.SuspendLayout(); // // groupBox2 // this.groupBox2.Controls.Add(this.LV_Result); this.groupBox2.Dock = System.Windows.Forms.DockStyle.Fill; - this.groupBox2.Location = new System.Drawing.Point(0, 67); + this.groupBox2.Location = new System.Drawing.Point(0, 156); this.groupBox2.Name = "groupBox2"; - this.groupBox2.Size = new System.Drawing.Size(482, 468); + this.groupBox2.Size = new System.Drawing.Size(484, 353); this.groupBox2.TabIndex = 13; this.groupBox2.TabStop = false; this.groupBox2.Text = "Результат"; @@ -79,7 +84,7 @@ private void InitializeComponent() listViewItem1}); this.LV_Result.Location = new System.Drawing.Point(3, 18); this.LV_Result.Name = "LV_Result"; - this.LV_Result.Size = new System.Drawing.Size(476, 447); + this.LV_Result.Size = new System.Drawing.Size(478, 332); this.LV_Result.TabIndex = 10; this.LV_Result.UseCompatibleStateImageBehavior = false; this.LV_Result.View = System.Windows.Forms.View.Details; @@ -87,28 +92,28 @@ private void InitializeComponent() // Table // this.Table.Text = "Таблица"; - this.Table.Width = 38; + this.Table.Width = 65; // // Result // this.Result.Text = "Статус"; - this.Result.Width = 40; + this.Result.Width = 62; // // tableLayoutPanel1 // this.tableLayoutPanel1.AutoSize = true; this.tableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.tableLayoutPanel1.ColumnCount = 2; - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel1.Controls.Add(this.B_Open, 0, 0); - this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel2, 1, 0); + this.tableLayoutPanel1.Controls.Add(this.FLP_Action, 1, 0); this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Bottom; - this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 535); + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 509); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; this.tableLayoutPanel1.RowCount = 1; - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel1.Size = new System.Drawing.Size(482, 37); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(484, 31); this.tableLayoutPanel1.TabIndex = 14; // // B_Open @@ -117,7 +122,7 @@ private void InitializeComponent() this.B_Open.AutoSize = true; this.B_Open.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.B_Open.Image = global::FIASUpdate.icons8.OpenedFolder16; - this.B_Open.Location = new System.Drawing.Point(3, 6); + this.B_Open.Location = new System.Drawing.Point(3, 3); this.B_Open.Name = "B_Open"; this.B_Open.Padding = new System.Windows.Forms.Padding(1); this.B_Open.Size = new System.Drawing.Size(115, 25); @@ -127,27 +132,30 @@ private void InitializeComponent() this.B_Open.UseVisualStyleBackColor = true; this.B_Open.Click += new System.EventHandler(this.B_Open_Click); // - // flowLayoutPanel2 + // FLP_Action // - this.flowLayoutPanel2.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.flowLayoutPanel2.AutoSize = true; - this.flowLayoutPanel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.flowLayoutPanel2.Controls.Add(this.B_Import); - this.flowLayoutPanel2.Controls.Add(this.B_Cancel); - this.flowLayoutPanel2.Location = new System.Drawing.Point(286, 3); - this.flowLayoutPanel2.Name = "flowLayoutPanel2"; - this.flowLayoutPanel2.Size = new System.Drawing.Size(193, 31); - this.flowLayoutPanel2.TabIndex = 11; + this.FLP_Action.Anchor = System.Windows.Forms.AnchorStyles.Right; + this.FLP_Action.AutoSize = true; + this.FLP_Action.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.FLP_Action.Controls.Add(this.B_Import); + this.FLP_Action.Controls.Add(this.B_Cancel); + this.FLP_Action.Location = new System.Drawing.Point(275, 0); + this.FLP_Action.Margin = new System.Windows.Forms.Padding(0); + this.FLP_Action.Name = "FLP_Action"; + this.FLP_Action.Size = new System.Drawing.Size(209, 31); + this.FLP_Action.TabIndex = 11; + this.FLP_Action.WrapContents = false; // // B_Import // this.B_Import.Anchor = System.Windows.Forms.AnchorStyles.Right; this.B_Import.AutoSize = true; this.B_Import.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.B_Import.Image = global::FIASUpdate.icons8.Replace16; this.B_Import.Location = new System.Drawing.Point(3, 3); this.B_Import.Name = "B_Import"; this.B_Import.Padding = new System.Windows.Forms.Padding(1); - this.B_Import.Size = new System.Drawing.Size(105, 25); + this.B_Import.Size = new System.Drawing.Size(121, 25); this.B_Import.TabIndex = 0; this.B_Import.Text = "Импортировать"; this.B_Import.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; @@ -160,7 +168,7 @@ private void InitializeComponent() this.B_Cancel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.B_Cancel.Enabled = false; this.B_Cancel.Image = global::FIASUpdate.icons8.Cancel16; - this.B_Cancel.Location = new System.Drawing.Point(114, 3); + this.B_Cancel.Location = new System.Drawing.Point(130, 3); this.B_Cancel.Name = "B_Cancel"; this.B_Cancel.Padding = new System.Windows.Forms.Padding(1); this.B_Cancel.Size = new System.Drawing.Size(76, 25); @@ -174,71 +182,124 @@ private void InitializeComponent() // this.groupBox1.AutoSize = true; this.groupBox1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.groupBox1.Controls.Add(this.flowLayoutPanel1); + this.groupBox1.Controls.Add(this.tableLayoutPanel2); this.groupBox1.Dock = System.Windows.Forms.DockStyle.Top; - this.groupBox1.Location = new System.Drawing.Point(0, 0); + this.groupBox1.Location = new System.Drawing.Point(0, 56); this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(482, 67); + this.groupBox1.Size = new System.Drawing.Size(484, 100); this.groupBox1.TabIndex = 12; this.groupBox1.TabStop = false; this.groupBox1.Text = "Параметры импорта"; // - // flowLayoutPanel1 - // - this.flowLayoutPanel1.AutoSize = true; - this.flowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.flowLayoutPanel1.Controls.Add(this.CB_OnlyEmpty); - this.flowLayoutPanel1.Controls.Add(this.CB_Shrink); - this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; - this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.TopDown; - this.flowLayoutPanel1.Location = new System.Drawing.Point(3, 18); - this.flowLayoutPanel1.Name = "flowLayoutPanel1"; - this.flowLayoutPanel1.Size = new System.Drawing.Size(476, 46); - this.flowLayoutPanel1.TabIndex = 2; - this.flowLayoutPanel1.WrapContents = false; + // tableLayoutPanel2 + // + this.tableLayoutPanel2.AutoSize = true; + this.tableLayoutPanel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.tableLayoutPanel2.ColumnCount = 3; + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel2.Controls.Add(this.CB_OnlyEmpty, 1, 2); + this.tableLayoutPanel2.Controls.Add(this.B_Select, 2, 0); + this.tableLayoutPanel2.Controls.Add(this.label2, 0, 0); + this.tableLayoutPanel2.Controls.Add(this.TB_Archive, 1, 0); + this.tableLayoutPanel2.Controls.Add(this.label1, 0, 1); + this.tableLayoutPanel2.Controls.Add(this.TB_Version, 1, 1); + this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Top; + this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 18); + this.tableLayoutPanel2.Name = "tableLayoutPanel2"; + this.tableLayoutPanel2.RowCount = 3; + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel2.Size = new System.Drawing.Size(478, 79); + this.tableLayoutPanel2.TabIndex = 5; // // CB_OnlyEmpty // this.CB_OnlyEmpty.AutoSize = true; this.CB_OnlyEmpty.Checked = true; this.CB_OnlyEmpty.CheckState = System.Windows.Forms.CheckState.Checked; - this.CB_OnlyEmpty.Location = new System.Drawing.Point(3, 3); + this.CB_OnlyEmpty.Location = new System.Drawing.Point(54, 59); this.CB_OnlyEmpty.Name = "CB_OnlyEmpty"; this.CB_OnlyEmpty.Size = new System.Drawing.Size(249, 17); this.CB_OnlyEmpty.TabIndex = 2; this.CB_OnlyEmpty.Text = "Импортировать только в пустые таблицы"; this.CB_OnlyEmpty.UseVisualStyleBackColor = true; // - // CB_Shrink - // - this.CB_Shrink.AutoSize = true; - this.CB_Shrink.Checked = true; - this.CB_Shrink.CheckState = System.Windows.Forms.CheckState.Checked; - this.CB_Shrink.Location = new System.Drawing.Point(3, 26); - this.CB_Shrink.Name = "CB_Shrink"; - this.CB_Shrink.Size = new System.Drawing.Size(160, 17); - this.CB_Shrink.TabIndex = 3; - this.CB_Shrink.Text = "Сжать БД после импорта"; - this.CB_Shrink.UseVisualStyleBackColor = true; - // - // statusStrip1 - // - this.statusStrip1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.statusStrip1.GripStyle = System.Windows.Forms.ToolStripGripStyle.Visible; - this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + // B_Select + // + this.B_Select.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.B_Select.AutoSize = true; + this.B_Select.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.B_Select.Image = global::FIASUpdate.icons8.OpenedFolder16; + this.B_Select.Location = new System.Drawing.Point(397, 1); + this.B_Select.Margin = new System.Windows.Forms.Padding(0); + this.B_Select.Name = "B_Select"; + this.B_Select.Padding = new System.Windows.Forms.Padding(1); + this.B_Select.Size = new System.Drawing.Size(81, 25); + this.B_Select.TabIndex = 6; + this.B_Select.Text = "Выбрать"; + this.B_Select.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; + this.B_Select.UseVisualStyleBackColor = true; + this.B_Select.Click += new System.EventHandler(this.B_Select_Click); + // + // label2 + // + this.label2.Anchor = System.Windows.Forms.AnchorStyles.Right; + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(9, 7); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(39, 13); + this.label2.TabIndex = 4; + this.label2.Text = "Архив"; + // + // TB_Archive + // + this.TB_Archive.AllowDrop = true; + this.TB_Archive.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.TB_Archive.Location = new System.Drawing.Point(54, 3); + this.TB_Archive.Name = "TB_Archive"; + this.TB_Archive.Size = new System.Drawing.Size(340, 22); + this.TB_Archive.TabIndex = 3; + this.TB_Archive.TextChanged += new System.EventHandler(this.TB_Archive_TextChanged); + // + // label1 + // + this.label1.Anchor = System.Windows.Forms.AnchorStyles.Right; + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(3, 35); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(45, 13); + this.label1.TabIndex = 4; + this.label1.Text = "Версия"; + // + // TB_Version + // + this.TB_Version.Location = new System.Drawing.Point(54, 31); + this.TB_Version.Name = "TB_Version"; + this.TB_Version.ReadOnly = true; + this.TB_Version.Size = new System.Drawing.Size(100, 22); + this.TB_Version.TabIndex = 6; + // + // Status + // + this.Status.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.Status.GripStyle = System.Windows.Forms.ToolStripGripStyle.Visible; + this.Status.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.TS_Progress, this.TS_Stopwatch}); - this.statusStrip1.Location = new System.Drawing.Point(0, 572); - this.statusStrip1.Name = "statusStrip1"; - this.statusStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional; - this.statusStrip1.Size = new System.Drawing.Size(482, 22); - this.statusStrip1.TabIndex = 15; - this.statusStrip1.Text = "statusStrip1"; + this.Status.Location = new System.Drawing.Point(0, 540); + this.Status.Name = "Status"; + this.Status.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional; + this.Status.Size = new System.Drawing.Size(484, 22); + this.Status.TabIndex = 15; + this.Status.Text = "statusStrip1"; // // TS_Progress // this.TS_Progress.Name = "TS_Progress"; - this.TS_Progress.Size = new System.Drawing.Size(409, 17); + this.TS_Progress.Size = new System.Drawing.Size(411, 17); this.TS_Progress.Spring = true; this.TS_Progress.Status = "-"; this.TS_Progress.Text = "Статус: - -"; @@ -251,21 +312,34 @@ private void InitializeComponent() this.TS_Stopwatch.ShowText = false; this.TS_Stopwatch.Size = new System.Drawing.Size(58, 20); // + // Info + // + this.Info.AutoSize = true; + this.Info.Dock = System.Windows.Forms.DockStyle.Top; + this.Info.Location = new System.Drawing.Point(0, 0); + this.Info.Name = "Info"; + this.Info.Size = new System.Drawing.Size(484, 56); + this.Info.Subjects = null; + this.Info.TabIndex = 19; + this.Info.Version = new System.DateTime(((long)(0))); + // // FormImportFull // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = global::FIASUpdate.Properties.Settings.Default.DefaultBackColor; - this.ClientSize = new System.Drawing.Size(482, 594); + this.ClientSize = new System.Drawing.Size(484, 562); this.Controls.Add(this.groupBox2); this.Controls.Add(this.tableLayoutPanel1); this.Controls.Add(this.groupBox1); - this.Controls.Add(this.statusStrip1); + this.Controls.Add(this.Info); + this.Controls.Add(this.Status); this.DataBindings.Add(new System.Windows.Forms.Binding("Font", global::FIASUpdate.Properties.Settings.Default, "DefaultFont", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); this.DataBindings.Add(new System.Windows.Forms.Binding("ForeColor", global::FIASUpdate.Properties.Settings.Default, "DefaultForeColor", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); this.DataBindings.Add(new System.Windows.Forms.Binding("BackColor", global::FIASUpdate.Properties.Settings.Default, "DefaultBackColor", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); this.Font = global::FIASUpdate.Properties.Settings.Default.DefaultFont; this.ForeColor = global::FIASUpdate.Properties.Settings.Default.DefaultForeColor; + this.MinimumSize = new System.Drawing.Size(500, 600); this.Name = "FormImportFull"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Импорт БД"; @@ -274,14 +348,14 @@ private void InitializeComponent() this.groupBox2.ResumeLayout(false); this.tableLayoutPanel1.ResumeLayout(false); this.tableLayoutPanel1.PerformLayout(); - this.flowLayoutPanel2.ResumeLayout(false); - this.flowLayoutPanel2.PerformLayout(); + this.FLP_Action.ResumeLayout(false); + this.FLP_Action.PerformLayout(); this.groupBox1.ResumeLayout(false); this.groupBox1.PerformLayout(); - this.flowLayoutPanel1.ResumeLayout(false); - this.flowLayoutPanel1.PerformLayout(); - this.statusStrip1.ResumeLayout(false); - this.statusStrip1.PerformLayout(); + this.tableLayoutPanel2.ResumeLayout(false); + this.tableLayoutPanel2.PerformLayout(); + this.Status.ResumeLayout(false); + this.Status.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); @@ -296,14 +370,19 @@ private void InitializeComponent() private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; private System.Windows.Forms.Button B_Import; private System.Windows.Forms.GroupBox groupBox1; - private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; private System.Windows.Forms.CheckBox CB_OnlyEmpty; - private System.Windows.Forms.CheckBox CB_Shrink; - private System.Windows.Forms.StatusStrip statusStrip1; - private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2; + private System.Windows.Forms.StatusStrip Status; + private System.Windows.Forms.FlowLayoutPanel FLP_Action; private System.Windows.Forms.Button B_Cancel; private Controls.ToolStripTaskProgress TS_Progress; private JANL.Controls.ToolStripStopwatch TS_Stopwatch; private System.Windows.Forms.Button B_Open; + private Controls.UC_DatabaseInfo Info; + private Controls.TextBoxFileDrop TB_Archive; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; + private System.Windows.Forms.Button B_Select; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox TB_Version; } } \ No newline at end of file diff --git a/FIASUpdate/Forms/FormImportFull.cs b/FIASUpdate/Forms/FormImportFull.cs index 8bae845..581ba62 100644 --- a/FIASUpdate/Forms/FormImportFull.cs +++ b/FIASUpdate/Forms/FormImportFull.cs @@ -1,5 +1,6 @@ -using FIASUpdate.Models; -using JANL; +using FIAS.Core.Stores; +using FIASUpdate.Models; +using FIASUpdate.Properties; using JANL.Extensions; using System; using System.Collections.Generic; @@ -13,68 +14,104 @@ namespace FIASUpdate.Forms { public partial class FormImportFull : Form { + private static readonly Settings Settings = Settings.Default; + private readonly FIASDatabaseStore Store = new FIASDatabaseStore(Settings.SQLConnection); + private FIASArchiveFull Archive; private CancellationTokenSource CTS; + private List Subjects; + private DateTime Version; public FormImportFull() { InitializeComponent(); } - private void AddResult(string table, string status) + private void AddResult(TableImportResult result) { - var LVI = LV_Result.Items.Add(table); - LVI.SubItems.Add(status); + var LVI = LV_Result.Items.Add(result.Table); + LVI.SubItems.Add(result.Status); LV_Result.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); } - private void FIAS_ResultChanged(object sender, ResultAddedEventArgs e) => AddResult(e.Table, e.Status); + private void FIAS_ResultChanged(object sender, ResultAddedEventArgs e) => AddResult(e.Result); + + private void RefreshDatabase() + { + var version = Store.GetVersion(); + var subjects = Store.GetSubjects(); + if (subjects.Count == 0) + { + this.ShowError("В свойствах БД не указан список субъектов РФ. Импорт невозможно."); + return; + } + Version = version.Value; + Subjects = subjects; + Info.Version = Version; + Info.Subjects = Subjects; + + RefreshUI(); + } private void RefreshUI() { - B_Import.Enabled = CTS == null; + B_Import.Enabled = CTS == null && Archive != null && Archive.Exsists; B_Cancel.Enabled = CTS != null; } - private void SetResult(IReadOnlyDictionary Result) + private void SetResult(IReadOnlyList Result) { LV_Result.BeginUpdate(); LV_Result.Items.Clear(); - foreach (var KV in Result) + foreach (var R in Result) { - var LVI = LV_Result.Items.Add(KV.Key); - LVI.SubItems.Add(KV.Value); + var LVI = LV_Result.Items.Add(R.Table); + LVI.SubItems.Add(R.Status); } LV_Result.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); LV_Result.EndUpdate(); } - private async Task StartImport() + private async Task StartTask(Func task) { CTS = new CancellationTokenSource(); RefreshUI(); TS_Stopwatch.Start(); + try + { + await task(CTS.Token); + } + catch (Exception ex) { this.ShowException(ex); } + finally + { + CTS.Dispose(); + CTS = null; + TS_Stopwatch.Stop(); + RefreshUI(); + } + } + + private async Task TaskImport(CancellationToken token) + { try { LV_Result.Items.Clear(); - var Options = new ImportFullOptions + using (var FIAS = new DBImportFull(Archive) { - OnlyEmpty = CB_OnlyEmpty.Checked, - ShrinkDatabase = CB_Shrink.Checked - }; - using (var FIAS = new DBImportFull(Options)) + Subjects = Subjects, + OnlyEmpty = CB_OnlyEmpty.Checked + }) { FIAS.ResultAdded += FIAS_ResultChanged; await Task.Run(() => FIAS.Import(TS_Progress.Progress, CTS.Token)); SetResult(FIAS.Result); } + TS_Progress.Status = "Импорт завершён"; + FLP_Action.Enabled = false; } - catch (Exception ex) { this.ShowException(ex); } - finally + catch (OperationCanceledException) { - CTS.Dispose(); - CTS = null; - RefreshUI(); - TS_Stopwatch.Stop(); + TS_Progress.Status = "Импорт отменён"; + TS_Progress.Value = "-"; } } @@ -88,12 +125,7 @@ private void B_Cancel_Click(object sender, EventArgs e) private void B_Import_Click(object sender, EventArgs e) { - _ = StartImport(); - } - - private void FormImportFull_Load(object sender, EventArgs e) - { - Icon = Owner.Icon; + _ = StartTask(TaskImport); } private void B_Open_Click(object sender, EventArgs e) @@ -102,6 +134,11 @@ private void B_Open_Click(object sender, EventArgs e) Process.Start(FIASProperties.GAR_Full); } + private void B_Select_Click(object sender, EventArgs e) + { + TB_Archive.SelectFile(); + } + private void FormImportFull_FormClosing(object sender, FormClosingEventArgs e) { if (CTS != null) @@ -111,6 +148,23 @@ private void FormImportFull_FormClosing(object sender, FormClosingEventArgs e) } } + private void FormImportFull_Load(object sender, EventArgs e) + { + Icon = Owner.Icon; + LV_Result.Items.Clear(); + LV_Result.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize); + RefreshDatabase(); + } + + private void TB_Archive_TextChanged(object sender, EventArgs e) + { + // TB_Archive.Text + Archive = new FIASArchiveFull(TB_Archive.Text); + Archive.ExtractVersion(); + TB_Version.Text = Archive.Date == default ? "" : $"{Archive.Date:yyyy.MM.dd}"; + RefreshUI(); + } + #endregion UI Events } } \ No newline at end of file diff --git a/FIASUpdate/Forms/FormImportFull.resx b/FIASUpdate/Forms/FormImportFull.resx index 174ebc7..441d946 100644 --- a/FIASUpdate/Forms/FormImportFull.resx +++ b/FIASUpdate/Forms/FormImportFull.resx @@ -117,7 +117,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + 17, 17 \ No newline at end of file diff --git a/FIASUpdate/Forms/FormSettings.Designer.cs b/FIASUpdate/Forms/FormSettings.Designer.cs index f6fbbb5..dc3a345 100644 --- a/FIASUpdate/Forms/FormSettings.Designer.cs +++ b/FIASUpdate/Forms/FormSettings.Designer.cs @@ -28,8 +28,7 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - System.Windows.Forms.ListViewItem listViewItem1 = new System.Windows.Forms.ListViewItem(""); - this.Info = new FIASUpdate.Controls.UC_DatabaseInfo(); + System.Windows.Forms.ListViewItem listViewItem3 = new System.Windows.Forms.ListViewItem(""); this.textBox1 = new System.Windows.Forms.TextBox(); this.B_SQLConnection = new System.Windows.Forms.Button(); this.textBox2 = new System.Windows.Forms.TextBox(); @@ -46,22 +45,22 @@ private void InitializeComponent() this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.LV_Tables = new System.Windows.Forms.ListView(); this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.label3 = new System.Windows.Forms.Label(); + this.TB_Version = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.TB_Subject = new System.Windows.Forms.TextBox(); + this.B_Subjects = new System.Windows.Forms.Button(); this.tableLayoutPanel2.SuspendLayout(); this.tableLayoutPanel3.SuspendLayout(); this.groupBox3.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.tableLayoutPanel1.SuspendLayout(); this.SuspendLayout(); // - // Info - // - this.Info.AutoSize = true; - this.Info.Dock = System.Windows.Forms.DockStyle.Bottom; - this.Info.Location = new System.Drawing.Point(0, 475); - this.Info.Name = "Info"; - this.Info.Size = new System.Drawing.Size(544, 56); - this.Info.Subjects = null; - this.Info.TabIndex = 10; - this.Info.Version = new System.DateTime(((long)(0))); - // // textBox1 // this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); @@ -69,7 +68,7 @@ private void InitializeComponent() this.textBox1.Location = new System.Drawing.Point(82, 4); this.textBox1.Name = "textBox1"; this.textBox1.ReadOnly = true; - this.textBox1.Size = new System.Drawing.Size(372, 22); + this.textBox1.Size = new System.Drawing.Size(360, 22); this.textBox1.TabIndex = 1; this.textBox1.Text = global::FIASUpdate.Properties.Settings.Default.SQLConnection; // @@ -79,7 +78,7 @@ private void InitializeComponent() this.B_SQLConnection.AutoSize = true; this.B_SQLConnection.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.B_SQLConnection.Image = global::FIASUpdate.icons8.PencilDrawing16; - this.B_SQLConnection.Location = new System.Drawing.Point(460, 3); + this.B_SQLConnection.Location = new System.Drawing.Point(448, 3); this.B_SQLConnection.Name = "B_SQLConnection"; this.B_SQLConnection.Padding = new System.Windows.Forms.Padding(1); this.B_SQLConnection.Size = new System.Drawing.Size(81, 25); @@ -96,7 +95,7 @@ private void InitializeComponent() this.textBox2.Location = new System.Drawing.Point(82, 35); this.textBox2.Name = "textBox2"; this.textBox2.ReadOnly = true; - this.textBox2.Size = new System.Drawing.Size(372, 22); + this.textBox2.Size = new System.Drawing.Size(360, 22); this.textBox2.TabIndex = 1; this.textBox2.Text = global::FIASUpdate.Properties.Settings.Default.XMLPath; // @@ -134,13 +133,13 @@ private void InitializeComponent() this.tableLayoutPanel2.Controls.Add(this.label1, 0, 0); this.tableLayoutPanel2.Controls.Add(this.label2, 0, 1); this.tableLayoutPanel2.Controls.Add(this.B_XMLPath, 2, 1); - this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Top; - this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 18); this.tableLayoutPanel2.Name = "tableLayoutPanel2"; this.tableLayoutPanel2.RowCount = 2; this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel2.Size = new System.Drawing.Size(544, 62); + this.tableLayoutPanel2.Size = new System.Drawing.Size(532, 62); this.tableLayoutPanel2.TabIndex = 9; // // B_XMLPath @@ -149,7 +148,7 @@ private void InitializeComponent() this.B_XMLPath.AutoSize = true; this.B_XMLPath.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.B_XMLPath.Image = global::FIASUpdate.icons8.OpenedFolder16; - this.B_XMLPath.Location = new System.Drawing.Point(460, 34); + this.B_XMLPath.Location = new System.Drawing.Point(448, 34); this.B_XMLPath.Name = "B_XMLPath"; this.B_XMLPath.Padding = new System.Windows.Forms.Padding(1); this.B_XMLPath.Size = new System.Drawing.Size(81, 25); @@ -161,10 +160,11 @@ private void InitializeComponent() // // B_Save // + this.B_Save.Anchor = System.Windows.Forms.AnchorStyles.Right; this.B_Save.AutoSize = true; this.B_Save.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.B_Save.Image = global::FIASUpdate.icons8.Save16; - this.B_Save.Location = new System.Drawing.Point(449, 3); + this.B_Save.Location = new System.Drawing.Point(437, 3); this.B_Save.Name = "B_Save"; this.B_Save.Padding = new System.Windows.Forms.Padding(1); this.B_Save.Size = new System.Drawing.Size(92, 25); @@ -194,17 +194,16 @@ private void InitializeComponent() // this.tableLayoutPanel3.AutoSize = true; this.tableLayoutPanel3.ColumnCount = 2; - this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); this.tableLayoutPanel3.Controls.Add(this.B_Save, 1, 0); this.tableLayoutPanel3.Controls.Add(this.B_Refresh, 0, 0); this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Bottom; - this.tableLayoutPanel3.Location = new System.Drawing.Point(0, 531); + this.tableLayoutPanel3.Location = new System.Drawing.Point(3, 456); this.tableLayoutPanel3.Name = "tableLayoutPanel3"; this.tableLayoutPanel3.RowCount = 1; this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 31F)); - this.tableLayoutPanel3.Size = new System.Drawing.Size(544, 31); + this.tableLayoutPanel3.Size = new System.Drawing.Size(532, 31); this.tableLayoutPanel3.TabIndex = 8; // // columnHeader4 @@ -238,13 +237,13 @@ private void InitializeComponent() this.LV_Tables.FullRowSelect = true; this.LV_Tables.GridLines = true; this.LV_Tables.HideSelection = false; - listViewItem1.StateImageIndex = 0; + listViewItem3.StateImageIndex = 0; this.LV_Tables.Items.AddRange(new System.Windows.Forms.ListViewItem[] { - listViewItem1}); + listViewItem3}); this.LV_Tables.Location = new System.Drawing.Point(3, 18); this.LV_Tables.MultiSelect = false; this.LV_Tables.Name = "LV_Tables"; - this.LV_Tables.Size = new System.Drawing.Size(538, 392); + this.LV_Tables.Size = new System.Drawing.Size(526, 358); this.LV_Tables.TabIndex = 0; this.LV_Tables.UseCompatibleStateImageBehavior = false; this.LV_Tables.View = System.Windows.Forms.View.Details; @@ -253,23 +252,127 @@ private void InitializeComponent() // this.groupBox3.Controls.Add(this.LV_Tables); this.groupBox3.Dock = System.Windows.Forms.DockStyle.Fill; - this.groupBox3.Location = new System.Drawing.Point(0, 62); + this.groupBox3.Location = new System.Drawing.Point(3, 77); this.groupBox3.Name = "groupBox3"; - this.groupBox3.Size = new System.Drawing.Size(544, 413); + this.groupBox3.Size = new System.Drawing.Size(532, 379); this.groupBox3.TabIndex = 7; this.groupBox3.TabStop = false; this.groupBox3.Text = "Таблицы для импорта"; // + // groupBox1 + // + this.groupBox1.AutoSize = true; + this.groupBox1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.groupBox1.Controls.Add(this.tableLayoutPanel2); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Top; + this.groupBox1.Location = new System.Drawing.Point(3, 3); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(538, 83); + this.groupBox1.TabIndex = 11; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Настройки приложения"; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.groupBox3); + this.groupBox2.Controls.Add(this.tableLayoutPanel1); + this.groupBox2.Controls.Add(this.tableLayoutPanel3); + this.groupBox2.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox2.Location = new System.Drawing.Point(3, 86); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(538, 490); + this.groupBox2.TabIndex = 12; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "Настройки БД"; + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.AutoSize = true; + this.tableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.tableLayoutPanel1.ColumnCount = 3; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel1.Controls.Add(this.label3, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.TB_Version, 1, 0); + this.tableLayoutPanel1.Controls.Add(this.label4, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.TB_Subject, 1, 1); + this.tableLayoutPanel1.Controls.Add(this.B_Subjects, 2, 0); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Top; + this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 18); + this.tableLayoutPanel1.MinimumSize = new System.Drawing.Size(150, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 2; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.Size = new System.Drawing.Size(532, 59); + this.tableLayoutPanel1.TabIndex = 20; + // + // label3 + // + this.label3.Anchor = System.Windows.Forms.AnchorStyles.Right; + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(16, 9); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(45, 13); + this.label3.TabIndex = 0; + this.label3.Text = "Версия"; + // + // TB_Version + // + this.TB_Version.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.TB_Version.Location = new System.Drawing.Point(67, 4); + this.TB_Version.Name = "TB_Version"; + this.TB_Version.ReadOnly = true; + this.TB_Version.Size = new System.Drawing.Size(100, 22); + this.TB_Version.TabIndex = 1; + this.TB_Version.TabStop = false; + // + // label4 + // + this.label4.Anchor = System.Windows.Forms.AnchorStyles.Right; + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(3, 38); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(58, 13); + this.label4.TabIndex = 0; + this.label4.Text = "Субъекты"; + // + // TB_Subject + // + this.TB_Subject.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.tableLayoutPanel1.SetColumnSpan(this.TB_Subject, 2); + this.TB_Subject.Location = new System.Drawing.Point(67, 34); + this.TB_Subject.Name = "TB_Subject"; + this.TB_Subject.ReadOnly = true; + this.TB_Subject.Size = new System.Drawing.Size(462, 22); + this.TB_Subject.TabIndex = 1; + this.TB_Subject.TabStop = false; + // + // B_Subjects + // + this.B_Subjects.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.B_Subjects.AutoSize = true; + this.B_Subjects.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.B_Subjects.Image = global::FIASUpdate.icons8.PencilDrawing16; + this.B_Subjects.Location = new System.Drawing.Point(443, 3); + this.B_Subjects.Name = "B_Subjects"; + this.B_Subjects.Padding = new System.Windows.Forms.Padding(1); + this.B_Subjects.Size = new System.Drawing.Size(86, 25); + this.B_Subjects.TabIndex = 21; + this.B_Subjects.Text = "Субъекты"; + this.B_Subjects.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; + this.B_Subjects.UseVisualStyleBackColor = true; + this.B_Subjects.Click += new System.EventHandler(this.B_Subjects_Click); + // // FormSettings // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = global::FIASUpdate.Properties.Settings.Default.DefaultBackColor; - this.ClientSize = new System.Drawing.Size(544, 562); - this.Controls.Add(this.groupBox3); - this.Controls.Add(this.Info); - this.Controls.Add(this.tableLayoutPanel2); - this.Controls.Add(this.tableLayoutPanel3); + this.ClientSize = new System.Drawing.Size(544, 579); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.groupBox1); this.DataBindings.Add(new System.Windows.Forms.Binding("Font", global::FIASUpdate.Properties.Settings.Default, "DefaultFont", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); this.DataBindings.Add(new System.Windows.Forms.Binding("ForeColor", global::FIASUpdate.Properties.Settings.Default, "DefaultForeColor", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); this.DataBindings.Add(new System.Windows.Forms.Binding("BackColor", global::FIASUpdate.Properties.Settings.Default, "DefaultBackColor", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); @@ -279,6 +382,7 @@ private void InitializeComponent() this.MinimizeBox = false; this.MinimumSize = new System.Drawing.Size(560, 600); this.Name = "FormSettings"; + this.Padding = new System.Windows.Forms.Padding(3); this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Настройки"; this.Load += new System.EventHandler(this.FormSettings_Load); @@ -287,14 +391,18 @@ private void InitializeComponent() this.tableLayoutPanel3.ResumeLayout(false); this.tableLayoutPanel3.PerformLayout(); this.groupBox3.ResumeLayout(false); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); } #endregion - - private Controls.UC_DatabaseInfo Info; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.Button B_SQLConnection; private System.Windows.Forms.TextBox textBox2; @@ -311,5 +419,13 @@ private void InitializeComponent() private System.Windows.Forms.ColumnHeader columnHeader1; private System.Windows.Forms.ListView LV_Tables; private System.Windows.Forms.GroupBox groupBox3; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox TB_Version; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox TB_Subject; + private System.Windows.Forms.Button B_Subjects; } } \ No newline at end of file diff --git a/FIASUpdate/Forms/FormSettings.cs b/FIASUpdate/Forms/FormSettings.cs index 5ab0e7f..0529f9b 100644 --- a/FIASUpdate/Forms/FormSettings.cs +++ b/FIASUpdate/Forms/FormSettings.cs @@ -27,8 +27,11 @@ private void RefreshData() LV_Tables.Items.AddRange(Tables.Select(T => new TableLVI(T)).ToArray()); LV_Tables.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); LV_Tables.EndUpdate(); - Info.Version = Store.GetVersion(); - Info.Subjects = Store.GetSubjects(); + + var version = Store.GetVersion(); + var subjects = Store.GetSubjects(); + TB_Subject.Text = subjects is null ? "" : string.Join(" ", subjects); + TB_Version.Text = version is null ? "" : $"{version:yyyy.MM.dd}"; } private void SaveData() @@ -81,6 +84,14 @@ private void FormSettings_Load(object sender, EventArgs e) LV_Tables.Items.Clear(); } + private void B_Subjects_Click(object sender, EventArgs e) + { + using (var F = new FormSubjectList()) + { + F.ShowDialog(this); + } + } + #endregion UIEvents } } \ No newline at end of file diff --git a/FIASUpdate/Forms/FormSubjectList.Designer.cs b/FIASUpdate/Forms/FormSubjectList.Designer.cs new file mode 100644 index 0000000..42decca --- /dev/null +++ b/FIASUpdate/Forms/FormSubjectList.Designer.cs @@ -0,0 +1,203 @@ +namespace FIASUpdate.Forms +{ + partial class FormSubjectList + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.LV_Subjects = new System.Windows.Forms.ListView(); + this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); + this.B_Save = new System.Windows.Forms.Button(); + this.B_Refresh = new System.Windows.Forms.Button(); + this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this.B_SelectAll = new System.Windows.Forms.Button(); + this.B_DeselectAll = new System.Windows.Forms.Button(); + this.tableLayoutPanel3.SuspendLayout(); + this.flowLayoutPanel1.SuspendLayout(); + this.SuspendLayout(); + // + // LV_Subjects + // + this.LV_Subjects.CheckBoxes = true; + this.LV_Subjects.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnHeader1, + this.columnHeader2}); + this.LV_Subjects.Dock = System.Windows.Forms.DockStyle.Fill; + this.LV_Subjects.FullRowSelect = true; + this.LV_Subjects.GridLines = true; + this.LV_Subjects.HideSelection = false; + this.LV_Subjects.Location = new System.Drawing.Point(5, 36); + this.LV_Subjects.Name = "LV_Subjects"; + this.LV_Subjects.Size = new System.Drawing.Size(341, 390); + this.LV_Subjects.TabIndex = 0; + this.LV_Subjects.UseCompatibleStateImageBehavior = false; + this.LV_Subjects.View = System.Windows.Forms.View.Details; + // + // columnHeader1 + // + this.columnHeader1.Text = "Код"; + // + // columnHeader2 + // + this.columnHeader2.Text = "Наименование"; + this.columnHeader2.Width = 119; + // + // tableLayoutPanel3 + // + this.tableLayoutPanel3.AutoSize = true; + this.tableLayoutPanel3.ColumnCount = 2; + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel3.Controls.Add(this.B_Save, 1, 0); + this.tableLayoutPanel3.Controls.Add(this.B_Refresh, 0, 0); + this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Bottom; + this.tableLayoutPanel3.Location = new System.Drawing.Point(5, 426); + this.tableLayoutPanel3.Name = "tableLayoutPanel3"; + this.tableLayoutPanel3.RowCount = 1; + this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel3.Size = new System.Drawing.Size(341, 31); + this.tableLayoutPanel3.TabIndex = 9; + // + // B_Save + // + this.B_Save.Anchor = System.Windows.Forms.AnchorStyles.Right; + this.B_Save.AutoSize = true; + this.B_Save.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.B_Save.Image = global::FIASUpdate.icons8.Save16; + this.B_Save.Location = new System.Drawing.Point(246, 3); + this.B_Save.Name = "B_Save"; + this.B_Save.Padding = new System.Windows.Forms.Padding(1); + this.B_Save.Size = new System.Drawing.Size(92, 25); + this.B_Save.TabIndex = 2; + this.B_Save.Text = "Сохранить"; + this.B_Save.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; + this.B_Save.UseVisualStyleBackColor = true; + this.B_Save.Click += new System.EventHandler(this.B_Save_Click); + // + // B_Refresh + // + this.B_Refresh.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.B_Refresh.AutoSize = true; + this.B_Refresh.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.B_Refresh.Image = global::FIASUpdate.icons8.Replace16; + this.B_Refresh.Location = new System.Drawing.Point(3, 3); + this.B_Refresh.Name = "B_Refresh"; + this.B_Refresh.Padding = new System.Windows.Forms.Padding(1); + this.B_Refresh.Size = new System.Drawing.Size(89, 25); + this.B_Refresh.TabIndex = 2; + this.B_Refresh.Text = "Обновить"; + this.B_Refresh.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; + this.B_Refresh.UseVisualStyleBackColor = true; + this.B_Refresh.Click += new System.EventHandler(this.B_Refresh_Click); + // + // flowLayoutPanel1 + // + this.flowLayoutPanel1.AutoSize = true; + this.flowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.flowLayoutPanel1.Controls.Add(this.B_SelectAll); + this.flowLayoutPanel1.Controls.Add(this.B_DeselectAll); + this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Top; + this.flowLayoutPanel1.Location = new System.Drawing.Point(5, 5); + this.flowLayoutPanel1.Name = "flowLayoutPanel1"; + this.flowLayoutPanel1.Size = new System.Drawing.Size(341, 31); + this.flowLayoutPanel1.TabIndex = 10; + // + // B_SelectAll + // + this.B_SelectAll.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.B_SelectAll.AutoSize = true; + this.B_SelectAll.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.B_SelectAll.Location = new System.Drawing.Point(3, 3); + this.B_SelectAll.MinimumSize = new System.Drawing.Size(100, 0); + this.B_SelectAll.Name = "B_SelectAll"; + this.B_SelectAll.Padding = new System.Windows.Forms.Padding(1); + this.B_SelectAll.Size = new System.Drawing.Size(100, 25); + this.B_SelectAll.TabIndex = 11; + this.B_SelectAll.Text = "Выбрать все"; + this.B_SelectAll.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; + this.B_SelectAll.UseVisualStyleBackColor = true; + this.B_SelectAll.Click += new System.EventHandler(this.B_SelectAll_Click); + // + // B_DeselectAll + // + this.B_DeselectAll.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.B_DeselectAll.AutoSize = true; + this.B_DeselectAll.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.B_DeselectAll.Location = new System.Drawing.Point(109, 3); + this.B_DeselectAll.MinimumSize = new System.Drawing.Size(100, 0); + this.B_DeselectAll.Name = "B_DeselectAll"; + this.B_DeselectAll.Padding = new System.Windows.Forms.Padding(1); + this.B_DeselectAll.Size = new System.Drawing.Size(100, 25); + this.B_DeselectAll.TabIndex = 11; + this.B_DeselectAll.Text = "Убрать все"; + this.B_DeselectAll.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; + this.B_DeselectAll.UseVisualStyleBackColor = true; + this.B_DeselectAll.Click += new System.EventHandler(this.B_DeselectAll_Click); + // + // FormSubjectList + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = global::FIASUpdate.Properties.Settings.Default.DefaultBackColor; + this.ClientSize = new System.Drawing.Size(351, 462); + this.Controls.Add(this.LV_Subjects); + this.Controls.Add(this.flowLayoutPanel1); + this.Controls.Add(this.tableLayoutPanel3); + this.DataBindings.Add(new System.Windows.Forms.Binding("Font", global::FIASUpdate.Properties.Settings.Default, "DefaultFont", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.DataBindings.Add(new System.Windows.Forms.Binding("ForeColor", global::FIASUpdate.Properties.Settings.Default, "DefaultForeColor", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.DataBindings.Add(new System.Windows.Forms.Binding("BackColor", global::FIASUpdate.Properties.Settings.Default, "DefaultBackColor", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.Font = global::FIASUpdate.Properties.Settings.Default.DefaultFont; + this.ForeColor = global::FIASUpdate.Properties.Settings.Default.DefaultForeColor; + this.MinimumSize = new System.Drawing.Size(350, 500); + this.Name = "FormSubjectList"; + this.Padding = new System.Windows.Forms.Padding(5); + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Список субъектоа БД"; + this.Load += new System.EventHandler(this.FormSubjectList_Load); + this.tableLayoutPanel3.ResumeLayout(false); + this.tableLayoutPanel3.PerformLayout(); + this.flowLayoutPanel1.ResumeLayout(false); + this.flowLayoutPanel1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ListView LV_Subjects; + private System.Windows.Forms.ColumnHeader columnHeader1; + private System.Windows.Forms.ColumnHeader columnHeader2; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3; + private System.Windows.Forms.Button B_Save; + private System.Windows.Forms.Button B_Refresh; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; + private System.Windows.Forms.Button B_SelectAll; + private System.Windows.Forms.Button B_DeselectAll; + } +} \ No newline at end of file diff --git a/FIASUpdate/Forms/FormSubjectList.cs b/FIASUpdate/Forms/FormSubjectList.cs new file mode 100644 index 0000000..8a866cb --- /dev/null +++ b/FIASUpdate/Forms/FormSubjectList.cs @@ -0,0 +1,85 @@ +using FIAS.Core.Stores; +using System; +using System.Data; +using System.Linq; +using System.Windows.Forms; + +namespace FIASUpdate.Forms +{ + public partial class FormSubjectList : Form + { + private readonly FIASDatabaseStore Store = new FIASDatabaseStore(FIASProperties.SQLConnection); + + public FormSubjectList() + { + InitializeComponent(); + } + + private void CheckItems(bool state) + { + LV_Subjects.BeginUpdate(); + foreach (SubjectLVI item in LV_Subjects.Items) + { + item.Checked = state; + } + LV_Subjects.EndUpdate(); + } + + private void LoadData() + { + var subjects = Store.GetSubjects(); + var items = SubjectStore.GetSubjects() + .Select(KV => new SubjectLVI(KV.Key, KV.Value) { Checked = subjects.Contains(KV.Key) }) + .OrderByDescending(I => I.Checked) + .ThenBy(I => I.SubjectCode) + .ToArray(); + + LV_Subjects.BeginUpdate(); + LV_Subjects.Items.Clear(); + LV_Subjects.Items.AddRange(items); + LV_Subjects.AutoResizeColumn(0, ColumnHeaderAutoResizeStyle.HeaderSize); + LV_Subjects.AutoResizeColumn(1, ColumnHeaderAutoResizeStyle.ColumnContent); + LV_Subjects.EndUpdate(); + } + + private void SaveData() + { + var subjects = LV_Subjects.CheckedItems + .Cast() + .Select(I => I.SubjectCode) + .OrderBy(I => I) + .ToList(); + Store.SetSubjects(subjects); + LoadData(); + } + + #region UI Events + + private void B_DeselectAll_Click(object sender, EventArgs e) => CheckItems(false); + + private void B_Refresh_Click(object sender, EventArgs e) => LoadData(); + + private void B_Save_Click(object sender, EventArgs e) => SaveData(); + + private void B_SelectAll_Click(object sender, EventArgs e) => CheckItems(true); + + private void FormSubjectList_Load(object sender, EventArgs e) + { + Icon = Owner.Icon; + LoadData(); + } + + #endregion UI Events + + private class SubjectLVI : ListViewItem + { + public SubjectLVI(string code, string name) : base(code) + { + SubItems.Add(name); + } + + public string SubjectCode => Text; + public string SubjectName => SubItems[1].Text; + } + } +} \ No newline at end of file diff --git a/FIASUpdate/Forms/FormSubjectList.resx b/FIASUpdate/Forms/FormSubjectList.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/FIASUpdate/Forms/FormSubjectList.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/FIASUpdate/Models/FIASArchive.cs b/FIASUpdate/Models/FIASArchive.cs index 67d2014..fd3c481 100644 --- a/FIASUpdate/Models/FIASArchive.cs +++ b/FIASUpdate/Models/FIASArchive.cs @@ -1,5 +1,4 @@ -using FIAS.Core.API; -using System; +using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; @@ -7,35 +6,57 @@ namespace FIASUpdate.Models { - internal class FIASArchive + /// + /// Базовый класс архива ФИАС + /// + internal abstract class FIASArchive { - private readonly FileInfo File; - private readonly FIASInfo Info; + protected FileInfo Archive; - public FIASArchive(FIASInfo info) + protected FIASArchive(string path) { - Info = info; - File = new FileInfo(ArchivePath); - Refresh(); + SetArchivePath(path); } - public string ArchivePath => $@"{DirectoryPath}\gar_delta_xml.zip"; - public long? ArchiveSize { get; set; } - public DateTime Date => Info.Date; - public bool Exsists { get; private set; } - public string ExtractPath => $@"{DirectoryPath}\gar_delta_xml"; - public string TextVersion => Info.TextVersion; - public string URLDelta => Info.GarXMLDeltaURL; - public string URLFull => Info.GarXMLFullURL; - public int VersionId => Info.VersionId; - private string DirectoryPath => $@"{FIASProperties.GAR_Delta}\{Date:yyyy.MM.dd}"; + protected FIASArchive() { } + + /// + /// Путь до архива + /// + public string ArchivePath { get; protected set; } + + /// + /// Размер архива + /// + public long? ArchiveSize { get; protected set; } + + /// + /// Дата (версия) архива + /// + public DateTime Date { get; protected set; } + + /// + /// Существует ли архив + /// + public bool Exsists { get; protected set; } + + /// + /// Путь для извлечения архива + /// + public abstract string ExtractPath { get; } + /// + /// Извлечь файлы из архива для указанных субъектов + /// + /// Перечисление субъектов public void Extract(IEnumerable subjects) { var path = ArchivePath; using (var zip = ZipFile.OpenRead(path)) { + // Корневые файлы var root = zip.Entries.Where(E => !E.FullName.Contains(@"/")); + // Файлы субъектов var files = zip.Entries.Where(E => subjects.Any(S => E.FullName.Contains($@"{S}/"))); foreach (var item in root.Concat(files)) @@ -47,17 +68,49 @@ public void Extract(IEnumerable subjects) } } + /// + /// Извлечь дату (версию) архива + /// + public void ExtractVersion() + { + Refresh(); + if (!Exsists) { return; } + + var path = ArchivePath; + using (var zip = ZipFile.OpenRead(path)) + { + var entry = zip.Entries.First(E => E.FullName.Contains("version.txt")); + using (var S = entry.Open()) + { + using (var SR = new StreamReader(S)) + { + var version = SR.ReadLine(); + if (DateTime.TryParse(version, out var date)) + { + Date = date; + } + } + } + } + } + + /// + /// Обновить состояние файла архива + /// public void Refresh() { - File.Refresh(); - Exsists = File.Exists && IsValid(); + Archive.Refresh(); + Exsists = Archive.Exists && IsValid(); if (Exsists) { - ArchiveSize = File.Length; + ArchiveSize = Archive.Length; } } - private bool IsValid() + /// + /// Проверить корректность архива + /// + protected bool IsValid() { try { @@ -65,7 +118,7 @@ private bool IsValid() // Выдаст ошибку если файл в процессе записи или повреждён // Может зависнуть на повреждённом архиве // Нужна проверка хэша, но увы. Хэш в сделку не входил - using (var zip = ZipFile.OpenRead(File.FullName)) + using (var zip = ZipFile.OpenRead(Archive.FullName)) { return zip.Entries.Count > 0; } @@ -75,5 +128,12 @@ private bool IsValid() return false; } } + + protected void SetArchivePath(string path) + { + ArchivePath = path; + Archive = new FileInfo(ArchivePath); + Refresh(); + } } } \ No newline at end of file diff --git a/FIASUpdate/Models/FIASArchiveDelta.cs b/FIASUpdate/Models/FIASArchiveDelta.cs new file mode 100644 index 0000000..1c161c2 --- /dev/null +++ b/FIASUpdate/Models/FIASArchiveDelta.cs @@ -0,0 +1,25 @@ +using FIAS.Core.API; + +namespace FIASUpdate.Models +{ + /// + /// Класс дельта архива ФИАС + /// + internal class FIASArchiveDelta : FIASArchive + { + private readonly FIASInfo Info; + + public FIASArchiveDelta(FIASInfo info) + { + Info = info; + Date = info.Date; + SetArchivePath($@"{ExtractPath}.zip"); + } + + public override string ExtractPath => $@"{FIASProperties.GAR_Delta}\{Date:yyyy.MM.dd}\gar_delta_xml"; + public string TextVersion => Info.TextVersion; + public string URLDelta => Info.GarXMLDeltaURL; + public string URLFull => Info.GarXMLFullURL; + public int VersionId => Info.VersionId; + } +} \ No newline at end of file diff --git a/FIASUpdate/Models/FIASArchiveFull.cs b/FIASUpdate/Models/FIASArchiveFull.cs new file mode 100644 index 0000000..680b9c9 --- /dev/null +++ b/FIASUpdate/Models/FIASArchiveFull.cs @@ -0,0 +1,12 @@ +namespace FIASUpdate.Models +{ + /// + /// Класс полного архива ФИАС + /// + internal class FIASArchiveFull : FIASArchive + { + public FIASArchiveFull(string path) : base(path) { } + + public override string ExtractPath => $@"{FIASProperties.GAR_Full}\{Date:yyyy.MM.dd}\gar_full_xml"; + } +} \ No newline at end of file diff --git a/FIASUpdate/Models/FIASArchiveLVI.cs b/FIASUpdate/Models/FIASArchiveLVI.cs index c6a63d1..3084fe2 100644 --- a/FIASUpdate/Models/FIASArchiveLVI.cs +++ b/FIASUpdate/Models/FIASArchiveLVI.cs @@ -5,7 +5,7 @@ namespace FIASUpdate.Models { internal class FIASArchiveLVI : ListViewItem { - public FIASArchiveLVI(FIASArchive archive) : base($"{archive.Date:yyyy.MM.dd}") + public FIASArchiveLVI(FIASArchiveDelta archive) : base($"{archive.Date:yyyy.MM.dd}") { Archive = archive; SubItems.Add(Archive.TextVersion); @@ -14,7 +14,8 @@ public FIASArchiveLVI(FIASArchive archive) : base($"{archive.Date:yyyy.MM.dd}") Refresh(); } - public FIASArchive Archive { get; } + public FIASArchiveDelta Archive { get; } + public long? Size { get; set; } public string State { @@ -29,7 +30,8 @@ public string State public void Refresh() { Archive.Refresh(); - SubItems[2].Text = Archive.ArchiveSize.HasValue ? $"{Archive.ArchiveSize / Math.Pow(1024, 2):N2} МБ" : "-"; + var size = Archive.ArchiveSize ?? Size; + SubItems[2].Text = size.HasValue ? $"{size / Math.Pow(1024, 2):N2} МБ" : "-"; SubItems[3].Text = Archive.Exsists ? "Архив скачан" : "Архив не скачан"; } } diff --git a/FIASUpdate/Models/ImportOptions.cs b/FIASUpdate/Models/ImportOptions.cs deleted file mode 100644 index c4f733a..0000000 --- a/FIASUpdate/Models/ImportOptions.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Collections.Generic; - -namespace FIASUpdate.Models -{ - internal class ImportDeltaOptions : ImportOptions - { - /// - /// Список кодов субъектов РФ - /// - public IEnumerable Subjects { get; set; } - } - internal class ImportFullOptions : ImportOptions - { - /// - /// Импортировать только в пустые таблицы - /// - public bool OnlyEmpty { get; set; } - } - internal class ImportOptions - { - /// - /// Сжать БД после импорта - /// - public bool ShrinkDatabase { get; set; } - } -} \ No newline at end of file diff --git a/FIASUpdate/Program.cs b/FIASUpdate/Program.cs index 0ad4725..b5d92a3 100644 --- a/FIASUpdate/Program.cs +++ b/FIASUpdate/Program.cs @@ -1,4 +1,5 @@ -using FIASUpdate.Properties; +using FIAS.Core.Extensions; +using FIASUpdate.Properties; using JANL; using System; using System.ComponentModel; @@ -30,6 +31,7 @@ private static void Main() Settings.PropertyChanged += Default_PropertyChanged; Settings.Reload(); Defaults.Connection = Settings.SQLConnection; + SQLExtensions.DefaultConnection = Settings.SQLConnection; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); diff --git a/FIASUpdate/SyncEvent.cs b/FIASUpdate/SyncEvent.cs index b77b16b..9cfab41 100644 --- a/FIASUpdate/SyncEvent.cs +++ b/FIASUpdate/SyncEvent.cs @@ -20,19 +20,19 @@ public SyncEvent(object sender) /// /// Отправить асинхронное сообщение в контекст синхронизации. /// - public void PostEvent(EventHandler Handler, T Args) where T : EventArgs => Context.Post(GetCallback(Handler), Args); + public void PostEvent(EventHandler handler, T args) where T : EventArgs => Context.Post(GetCallback(handler), args); /// /// Отправить синхронное сообщение в контекст синхронизации. /// - public void SendEvent(EventHandler Handler, T Args) where T : EventArgs => Context.Send(GetCallback(Handler), Args); + public void SendEvent(EventHandler handler, T args) where T : EventArgs => Context.Send(GetCallback(handler), args); - private SendOrPostCallback GetCallback(EventHandler Handler) + private SendOrPostCallback GetCallback(EventHandler handler) { return (state) => { T E = (T)state; - Handler?.Invoke(Sender, E); + handler?.Invoke(Sender, E); }; } } diff --git a/FIAS_GAR/Security/adm.sql b/FIAS_GAR/Security/adm.sql index 2e98752..c0b7da5 100644 --- a/FIAS_GAR/Security/adm.sql +++ b/FIAS_GAR/Security/adm.sql @@ -18,6 +18,8 @@ + + GO GRANT SELECT ON SCHEMA::[adm] TO PUBLIC; diff --git a/FIAS_GAR/Security/mun.sql b/FIAS_GAR/Security/mun.sql index 5581f93..b6bff4c 100644 --- a/FIAS_GAR/Security/mun.sql +++ b/FIAS_GAR/Security/mun.sql @@ -16,6 +16,8 @@ + + GO GRANT SELECT ON SCHEMA::[mun] TO PUBLIC; diff --git a/LICENSE b/LICENSE index 4e90f61..6a84c0b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 Artyom Rybakov +Copyright (c) 2026 Artyom Rybakov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index db96845..ea3f1a7 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ ![Основная форма](/docs/assets/fias/main.png) ![Форма настроек](/docs/assets/fias/settings.png) ![Форма импорта](/docs/assets/fias/import-delta.png) -![Форма импорта](/docs/assets/fias/import.png) +![Форма импорта](/docs/assets/fias/import-full.png) ![Форма поиска адреса в БД](/docs/assets/fias/search.png) *P.S. Данное решение предназначено для разработчик работающих с .NET и SQL Server.* diff --git a/docs/assets/fias/import-delta.png b/docs/assets/fias/import-delta.png index cfac28e..42060dc 100644 Binary files a/docs/assets/fias/import-delta.png and b/docs/assets/fias/import-delta.png differ diff --git a/docs/assets/fias/import-full.png b/docs/assets/fias/import-full.png new file mode 100644 index 0000000..061933e Binary files /dev/null and b/docs/assets/fias/import-full.png differ diff --git a/docs/assets/fias/import.png b/docs/assets/fias/import.png deleted file mode 100644 index c230f3c..0000000 Binary files a/docs/assets/fias/import.png and /dev/null differ diff --git a/docs/assets/fias/main.png b/docs/assets/fias/main.png index 1135fb7..5fb8e5c 100644 Binary files a/docs/assets/fias/main.png and b/docs/assets/fias/main.png differ diff --git a/docs/assets/fias/settings.png b/docs/assets/fias/settings.png index 67753ba..e75b2a4 100644 Binary files a/docs/assets/fias/settings.png and b/docs/assets/fias/settings.png differ diff --git a/docs/fias-update/index.md b/docs/fias-update/index.md index 3f551ba..582bb16 100644 --- a/docs/fias-update/index.md +++ b/docs/fias-update/index.md @@ -8,7 +8,7 @@ description: "Приложение для импорта данный из XML Форма с настройками ![Настройки импорта](../assets/fias/settings.png) Вкладка с результатом импорта -![Основная форма](../assets/fias/import.png) +![Основная форма](../assets/fias/import-full.png) ## Поиск адреса в БД diff --git a/docs/fias-update/usage.md b/docs/fias-update/usage.md index 90346b2..5c75da9 100644 --- a/docs/fias-update/usage.md +++ b/docs/fias-update/usage.md @@ -14,7 +14,8 @@ description: "Импорт данных в БД FIAS_GAR" 1. Запустить FIASUpdate 2. Настроить соединение с БД **FIAS_GAR** -3. Указать в настройках каталог для хранения данных (**``**) и снять выбор с ненужных таблиц +3. Выбрать субъекты РФ для импорта +4. Указать в настройках каталог для хранения данных (**``**) и снять выбор с ненужных таблиц ## Импорт полной копии БД @@ -22,12 +23,12 @@ description: "Импорт данных в БД FIAS_GAR" Рекомендуется использовать менеджер загрузок для скачивания архива, например [Free Download Manager](https://www.freedownloadmanager.org/ru/) или что-то подобное. 1. Скачать архив с сайта ФИАС -2. Распаковать нужные субъекты и файлы из корня архива в **`\gar_xml\`** -3. Запустить FIASUpdate -4. Нажать `Импорт полной копии БД` +2. Запустить FIASUpdate +3. Нажать `Импорт полной копии БД` +4. Выбрать файл архива (Можно переташить на текстовое поле) 5. Нажать `Импортировать` и дождаться завершения импорта -![import](../assets/fias/import.png) +![import](../assets/fias/import-full.png) ## Импорт разностных копий БД diff --git a/mkdocs.yml b/mkdocs.yml index 194f9f5..09f982e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,7 +1,7 @@ site_name: Документация FIAS_GAR site_description: "Проект БД ФИАС ГАР для SQL Server и приложение для её обновления" site_url: https://virenbar.ru/FIAS_GAR/ -copyright: Copyright © 2025 Virenbar +copyright: Copyright © 2026 Virenbar theme: logo: assets/images/logo.png favicon: assets/images/favicon.ico