diff --git a/App.xaml b/App.xaml
index 9afe297..fe7f884 100644
--- a/App.xaml
+++ b/App.xaml
@@ -9,7 +9,9 @@
+
+
diff --git a/App.xaml.cs b/App.xaml.cs
index 06fc145..0c57ac0 100644
--- a/App.xaml.cs
+++ b/App.xaml.cs
@@ -1,5 +1,7 @@
using System.Windows;
using LibgenDesktop.Infrastructure;
+using LibgenDesktop.Models;
+using LibgenDesktop.ViewModels;
namespace LibgenDesktop
{
@@ -8,9 +10,38 @@ public partial class App : Application
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
- IWindowContext mainWindowContext = WindowManager.CreateWindow(RegisteredWindows.WindowKey.MAIN_WINDOW);
- mainWindowContext.Closed += (sender, args) => Shutdown();
- mainWindowContext.Show();
+ MainModel mainModel = new MainModel();
+ if (mainModel.LocalDatabaseStatus == MainModel.DatabaseStatus.OPENED)
+ {
+ ShowMainWindow(mainModel);
+ }
+ else
+ {
+ ShowCreateDatabaseWindow(mainModel);
+ }
+ }
+
+ private void ShowMainWindow(MainModel mainModel)
+ {
+ MainWindowViewModel mainWindowViewModel = new MainWindowViewModel(mainModel);
+ IWindowContext windowContext = WindowManager.CreateWindow(RegisteredWindows.WindowKey.MAIN_WINDOW, mainWindowViewModel);
+ windowContext.Closed += (sender, args) => Shutdown();
+ windowContext.Show();
+ }
+
+ private void ShowCreateDatabaseWindow(MainModel mainModel)
+ {
+ CreateDatabaseViewModel createDatabaseViewModel = new CreateDatabaseViewModel(mainModel);
+ IWindowContext windowContext = WindowManager.CreateWindow(RegisteredWindows.WindowKey.CREATE_DATABASE_WINDOW, createDatabaseViewModel);
+ bool? result = windowContext.ShowDialog();
+ if (result == true)
+ {
+ ShowMainWindow(mainModel);
+ }
+ else
+ {
+ Shutdown();
+ }
}
}
}
diff --git a/Common/Constants.cs b/Common/Constants.cs
index cfe6484..60e2168 100644
--- a/Common/Constants.cs
+++ b/Common/Constants.cs
@@ -2,39 +2,88 @@
{
internal static class Constants
{
+ public const string CURRENT_DATABASE_VERSION = "0.7";
+
public const int MAIN_WINDOW_MIN_WIDTH = 1000;
public const int MAIN_WINDOW_MIN_HEIGHT = 500;
- public const int BOOK_WINDOW_MIN_WIDTH = 1000;
- public const int BOOK_WINDOW_MIN_HEIGHT = 500;
+ public const int NON_FICTION_DETAILS_WINDOW_MIN_WIDTH = 1000;
+ public const int NON_FICTION_DETAILS_WINDOW_MIN_HEIGHT = 500;
+ public const int NON_FICTION_GRID_TITLE_COLUMN_MIN_WIDTH = 150;
+ public const int NON_FICTION_GRID_AUTHORS_COLUMN_MIN_WIDTH = 150;
+ public const int NON_FICTION_GRID_SERIES_COLUMN_MIN_WIDTH = 150;
+ public const int NON_FICTION_GRID_YEAR_COLUMN_MIN_WIDTH = 60;
+ public const int NON_FICTION_GRID_PUBLISHER_COLUMN_MIN_WIDTH = 150;
+ public const int NON_FICTION_GRID_FORMAT_COLUMN_MIN_WIDTH = 80;
+ public const int NON_FICTION_GRID_FILESIZE_COLUMN_MIN_WIDTH = 130;
+ public const int NON_FICTION_GRID_OCR_COLUMN_MIN_WIDTH = 55;
+ public const int FICTION_DETAILS_WINDOW_MIN_WIDTH = 600;
+ public const int FICTION_DETAILS_WINDOW_MIN_HEIGHT = 500;
+ public const int FICTION_GRID_TITLE_COLUMN_MIN_WIDTH = 150;
+ public const int FICTION_GRID_AUTHORS_COLUMN_MIN_WIDTH = 150;
+ public const int FICTION_GRID_SERIES_COLUMN_MIN_WIDTH = 150;
+ public const int FICTION_GRID_YEAR_COLUMN_MIN_WIDTH = 60;
+ public const int FICTION_GRID_PUBLISHER_COLUMN_MIN_WIDTH = 150;
+ public const int FICTION_GRID_FORMAT_COLUMN_MIN_WIDTH = 80;
+ public const int FICTION_GRID_FILESIZE_COLUMN_MIN_WIDTH = 130;
+ public const int SCI_MAG_DETAILS_WINDOW_MIN_WIDTH = 600;
+ public const int SCI_MAG_DETAILS_WINDOW_MIN_HEIGHT = 500;
+ public const int SCI_MAG_GRID_TITLE_COLUMN_MIN_WIDTH = 150;
+ public const int SCI_MAG_GRID_AUTHORS_COLUMN_MIN_WIDTH = 150;
+ public const int SCI_MAG_GRID_JOURNAL_COLUMN_MIN_WIDTH = 100;
+ public const int SCI_MAG_GRID_YEAR_COLUMN_MIN_WIDTH = 60;
+ public const int SCI_MAG_GRID_FILESIZE_COLUMN_MIN_WIDTH = 130;
+ public const int SCI_MAG_GRID_DOI_COLUMN_MIN_WIDTH = 150;
+ public const int ERROR_WINDOW_DEFAULT_WIDTH = 620;
+ public const int ERROR_WINDOW_DEFAULT_HEIGHT = 450;
public const int ERROR_WINDOW_MIN_WIDTH = 400;
public const int ERROR_WINDOW_MIN_HEIGHT = 300;
- public const int TITLE_COLUMN_MIN_WIDTH = 150;
- public const int AUTHORS_COLUMN_MIN_WIDTH = 150;
- public const int SERIES_COLUMN_MIN_WIDTH = 150;
- public const int YEAR_COLUMN_MIN_WIDTH = 60;
- public const int PUBLISHER_COLUMN_MIN_WIDTH = 150;
- public const int FORMAT_COLUMN_MIN_WIDTH = 80;
- public const int FILESIZE_COLUMN_MIN_WIDTH = 130;
- public const int OCR_COLUMN_MIN_WIDTH = 55;
+ public const int IMPORT_WINDOW_MIN_WIDTH = 500;
+ public const int IMPORT_WINDOW_MIN_HEIGHT = 400;
+ public const int CREATE_DATABASE_WINDOW_WIDTH = 500;
+ public const int SETTINGS_WINDOW_DEFAULT_WIDTH = 700;
+ public const int SETTINGS_WINDOW_DEFAULT_HEIGHT = 450;
+ public const int SETTINGS_WINDOW_MIN_WIDTH = 650;
+ public const int SETTINGS_WINDOW_MIN_HEIGHT = 450;
public const string DEFAULT_DATABASE_FILE_NAME = "libgen.db";
- public const int DEFAULT_MAIN_WINDOW_WIDTH = 1200;
+ public const int DEFAULT_MAIN_WINDOW_WIDTH = 1000;
public const int DEFAULT_MAIN_WINDOW_HEIGHT = 650;
- public const int DEFAULT_BOOK_WINDOW_WIDTH = 1200;
- public const int DEFAULT_BOOK_WINDOW_HEIGHT = 618;
- public const int DEFAULT_TITLE_COLUMN_WIDTH = 200;
- public const int DEFAULT_AUTHORS_COLUMN_WIDTH = 200;
- public const int DEFAULT_SERIES_COLUMN_WIDTH = 180;
- public const int DEFAULT_YEAR_COLUMN_WIDTH = 60;
- public const int DEFAULT_PUBLISHER_COLUMN_WIDTH = 180;
- public const int DEFAULT_FORMAT_COLUMN_WIDTH = 100;
- public const int DEFAULT_FILESIZE_COLUMN_WIDTH = 150;
- public const int DEFAULT_OCR_COLUMN_WIDTH = 55;
+ public const int DEFAULT_NON_FICTION_DETAILS_WINDOW_WIDTH = 1200;
+ public const int DEFAULT_NON_FICTION_DETAILS_WINDOW_HEIGHT = 618;
+ public const int DEFAULT_NON_FICTION_GRID_TITLE_COLUMN_WIDTH = 200;
+ public const int DEFAULT_NON_FICTION_GRID_AUTHORS_COLUMN_WIDTH = 200;
+ public const int DEFAULT_NON_FICTION_GRID_SERIES_COLUMN_WIDTH = 180;
+ public const int DEFAULT_NON_FICTION_GRID_YEAR_COLUMN_WIDTH = 60;
+ public const int DEFAULT_NON_FICTION_GRID_PUBLISHER_COLUMN_WIDTH = 180;
+ public const int DEFAULT_NON_FICTION_GRID_FORMAT_COLUMN_WIDTH = 100;
+ public const int DEFAULT_NON_FICTION_GRID_FILESIZE_COLUMN_WIDTH = 150;
+ public const int DEFAULT_NON_FICTION_GRID_OCR_COLUMN_WIDTH = 55;
+ public const int DEFAULT_FICTION_DETAILS_WINDOW_WIDTH = 850;
+ public const int DEFAULT_FICTION_DETAILS_WINDOW_HEIGHT = 650;
+ public const int DEFAULT_FICTION_GRID_TITLE_COLUMN_WIDTH = 200;
+ public const int DEFAULT_FICTION_GRID_AUTHORS_COLUMN_WIDTH = 200;
+ public const int DEFAULT_FICTION_GRID_SERIES_COLUMN_WIDTH = 180;
+ public const int DEFAULT_FICTION_GRID_YEAR_COLUMN_WIDTH = 60;
+ public const int DEFAULT_FICTION_GRID_PUBLISHER_COLUMN_WIDTH = 180;
+ public const int DEFAULT_FICTION_GRID_FORMAT_COLUMN_WIDTH = 100;
+ public const int DEFAULT_FICTION_GRID_FILESIZE_COLUMN_WIDTH = 150;
+ public const int DEFAULT_SCI_MAG_DETAILS_WINDOW_WIDTH = 910;
+ public const int DEFAULT_SCI_MAG_DETAILS_WINDOW_HEIGHT = 680;
+ public const int DEFAULT_SCI_MAG_GRID_TITLE_COLUMN_WIDTH = 270;
+ public const int DEFAULT_SCI_MAG_GRID_AUTHORS_COLUMN_WIDTH = 200;
+ public const int DEFAULT_SCI_MAG_GRID_JOURNAL_COLUMN_WIDTH = 120;
+ public const int DEFAULT_SCI_MAG_GRID_YEAR_COLUMN_WIDTH = 60;
+ public const int DEFAULT_SCI_MAG_GRID_FILESIZE_COLUMN_WIDTH = 150;
+ public const int DEFAULT_SCI_MAG_GRID_DOI_COLUMN_WIDTH = 290;
+ public const int DEFAULT_MAXIMUM_SEARCH_RESULT_COUNT = 50000;
public const int SEARCH_REPORT_PROGRESS_BATCH_SIZE = 2000;
public const int INSERT_TRANSACTION_BATCH = 500;
- public const string BOOK_COVER_URL_PREFIX = "http://libgen.io/covers/";
- public const string BOOK_DOWNLOAD_URL_PREFIX = "http://libgen.io/book/index.php?md5=";
+ public const string NON_FICTION_COVER_URL_PREFIX = "http://libgen.io/covers/";
+ public const string NON_FICTION_DOWNLOAD_URL_PREFIX = "http://libgen.io/book/index.php?md5=";
+ public const string FICTION_COVER_URL_PREFIX = "http://libgen.io/fictioncovers/";
+ public const string FICTION_DOWNLOAD_URL_PREFIX = "http://libgen.io/foreignfiction/ads.php?md5=";
+ public const string SCI_MAG_DOWNLOAD_URL_PREFIX = "http://libgen.io/scimag/ads.php?doi=";
}
}
diff --git a/Infrastructure/EventProvider.cs b/Infrastructure/EventProvider.cs
new file mode 100644
index 0000000..ae3decb
--- /dev/null
+++ b/Infrastructure/EventProvider.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace LibgenDesktop.Infrastructure
+{
+ public class EventProvider
+ {
+ private readonly Queue eventQueue;
+ private IEventListener eventListener;
+
+ public EventProvider()
+ {
+ eventQueue = new Queue();
+ eventListener = null;
+ }
+
+ public void SetEventListener(IEventListener eventListener)
+ {
+ this.eventListener = eventListener;
+ PassEvents();
+ }
+
+ public void RaiseEvent(ViewModelEvent viewModelEvent)
+ {
+ eventQueue.Enqueue(viewModelEvent);
+ PassEvents();
+ }
+
+ public void RaiseEvent(ViewModelEvent.RegisteredEventId eventId)
+ {
+ RaiseEvent(new ViewModelEvent(eventId));
+ }
+
+ private void PassEvents()
+ {
+ if (eventListener != null)
+ {
+ while (eventQueue.Any())
+ {
+ ViewModelEvent viewModelEvent = eventQueue.Dequeue();
+ eventListener.OnViewModelEvent(viewModelEvent);
+ }
+ }
+ }
+ }
+}
diff --git a/Infrastructure/IEventListener.cs b/Infrastructure/IEventListener.cs
new file mode 100644
index 0000000..66a3488
--- /dev/null
+++ b/Infrastructure/IEventListener.cs
@@ -0,0 +1,7 @@
+namespace LibgenDesktop.Infrastructure
+{
+ public interface IEventListener
+ {
+ void OnViewModelEvent(ViewModelEvent viewModelEvent);
+ }
+}
diff --git a/Infrastructure/OpenFileDialogResult.cs b/Infrastructure/OpenFileDialogResult.cs
index 849f3b7..dd67356 100644
--- a/Infrastructure/OpenFileDialogResult.cs
+++ b/Infrastructure/OpenFileDialogResult.cs
@@ -2,7 +2,7 @@
namespace LibgenDesktop.Infrastructure
{
- public class OpenFileDialogResult
+ internal class OpenFileDialogResult
{
public bool DialogResult { get; set; }
public List SelectedFilePaths { get; set; }
diff --git a/Infrastructure/RegisteredWindows.cs b/Infrastructure/RegisteredWindows.cs
index 5090bf1..6292e8d 100644
--- a/Infrastructure/RegisteredWindows.cs
+++ b/Infrastructure/RegisteredWindows.cs
@@ -10,9 +10,13 @@ internal static class RegisteredWindows
internal enum WindowKey
{
MAIN_WINDOW = 1,
- BOOK_DETAILS_WINDOW,
+ NON_FICTION_DETAILS_WINDOW,
+ FICTION_DETAILS_WINDOW,
+ SCI_MAG_DETAILS_WINDOW,
ERROR_WINDOW,
- SQL_DUMP_IMPORT_WINDOW
+ IMPORT_WINDOW,
+ CREATE_DATABASE_WINDOW,
+ SETTINGS_WINDOW
}
internal class RegisteredWindow
@@ -31,15 +35,22 @@ public RegisteredWindow(WindowKey windowKey, Type windowType, Type viewModelType
static RegisteredWindows()
{
- AllWindows = new Dictionary
- {
- { WindowKey.MAIN_WINDOW, new RegisteredWindow(WindowKey.MAIN_WINDOW, typeof(MainWindow), typeof(MainWindowViewModel)) },
- { WindowKey.BOOK_DETAILS_WINDOW, new RegisteredWindow(WindowKey.BOOK_DETAILS_WINDOW, typeof(BookDetailsWindow), typeof(BookDetailsWindowViewModel)) },
- { WindowKey.ERROR_WINDOW, new RegisteredWindow(WindowKey.ERROR_WINDOW, typeof(ErrorWindow), typeof(ErrorWindowViewModel)) },
- { WindowKey.SQL_DUMP_IMPORT_WINDOW, new RegisteredWindow(WindowKey.SQL_DUMP_IMPORT_WINDOW, typeof(SqlDumpImportWindow), typeof(SqlDumpImportWindowViewModel)) }
- };
+ AllWindows = new Dictionary();
+ RegisterWindow(WindowKey.MAIN_WINDOW, typeof(MainWindow), typeof(MainWindowViewModel));
+ RegisterWindow(WindowKey.NON_FICTION_DETAILS_WINDOW, typeof(NonFictionDetailsWindow), typeof(NonFictionDetailsWindowViewModel));
+ RegisterWindow(WindowKey.FICTION_DETAILS_WINDOW, typeof(FictionDetailsWindow), typeof(FictionDetailsWindowViewModel));
+ RegisterWindow(WindowKey.SCI_MAG_DETAILS_WINDOW, typeof(SciMagDetailsWindow), typeof(SciMagDetailsWindowViewModel));
+ RegisterWindow(WindowKey.ERROR_WINDOW, typeof(ErrorWindow), typeof(ErrorWindowViewModel));
+ RegisterWindow(WindowKey.IMPORT_WINDOW, typeof(ImportWindow), typeof(ImportWindowViewModel));
+ RegisterWindow(WindowKey.CREATE_DATABASE_WINDOW, typeof(CreateDatabaseWindow), typeof(CreateDatabaseViewModel));
+ RegisterWindow(WindowKey.SETTINGS_WINDOW, typeof(SettingsWindow), typeof(SettingsWindowViewModel));
}
public static Dictionary AllWindows { get; }
+
+ private static void RegisterWindow(WindowKey windowKey, Type windowType, Type viewModelType)
+ {
+ AllWindows.Add(windowKey, new RegisteredWindow(windowKey, windowType, viewModelType));
+ }
}
}
diff --git a/Infrastructure/SaveFileDialogParameters.cs b/Infrastructure/SaveFileDialogParameters.cs
new file mode 100644
index 0000000..591a6c5
--- /dev/null
+++ b/Infrastructure/SaveFileDialogParameters.cs
@@ -0,0 +1,11 @@
+namespace LibgenDesktop.Infrastructure
+{
+ internal class SaveFileDialogParameters
+ {
+ public string DialogTitle { get; set; }
+ public string Filter { get; set; }
+ public bool OverwritePrompt { get; set; }
+ public string InitialDirectory { get; set; }
+ public string InitialFileName { get; set; }
+ }
+}
diff --git a/Infrastructure/SaveFileDialogResult.cs b/Infrastructure/SaveFileDialogResult.cs
new file mode 100644
index 0000000..d86733d
--- /dev/null
+++ b/Infrastructure/SaveFileDialogResult.cs
@@ -0,0 +1,8 @@
+namespace LibgenDesktop.Infrastructure
+{
+ internal class SaveFileDialogResult
+ {
+ public bool DialogResult { get; set; }
+ public string SelectedFilePath { get; set; }
+ }
+}
diff --git a/Infrastructure/ViewModelEvent.cs b/Infrastructure/ViewModelEvent.cs
new file mode 100644
index 0000000..3d62a1d
--- /dev/null
+++ b/Infrastructure/ViewModelEvent.cs
@@ -0,0 +1,17 @@
+namespace LibgenDesktop.Infrastructure
+{
+ public class ViewModelEvent
+ {
+ public enum RegisteredEventId
+ {
+ FOCUS_SEARCH_TEXT_BOX = 1
+ }
+
+ public ViewModelEvent(RegisteredEventId eventId)
+ {
+ EventId = eventId;
+ }
+
+ public RegisteredEventId EventId { get; }
+ }
+}
diff --git a/Infrastructure/WindowContext.cs b/Infrastructure/WindowContext.cs
index 16c56e6..326e0db 100644
--- a/Infrastructure/WindowContext.cs
+++ b/Infrastructure/WindowContext.cs
@@ -64,7 +64,11 @@ public void Show(bool showMaximized = false)
Window.Owner = parentWindow;
Window.WindowStartupLocation = WindowStartupLocation.CenterOwner;
}
- return ShowDialog(showMaximized, true);
+ else
+ {
+ Window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
+ }
+ return ShowDialog(showMaximized, parentWindow == null);
}
public void Close()
@@ -102,10 +106,9 @@ protected virtual void OnClosed()
Closed?.Invoke(this, EventArgs.Empty);
}
- private bool? ShowDialog(bool showMaximized, bool hasOwner)
+ private bool? ShowDialog(bool showMaximized, bool showInTaskbar)
{
- Window.WindowStartupLocation = hasOwner ? WindowStartupLocation.CenterOwner : WindowStartupLocation.CenterScreen;
- Window.ShowInTaskbar = false;
+ Window.ShowInTaskbar = showInTaskbar;
Window.WindowState = GetWindowState(showMaximized);
return Window.ShowDialog();
}
diff --git a/Infrastructure/WindowManager.cs b/Infrastructure/WindowManager.cs
index 19ea27a..258060a 100644
--- a/Infrastructure/WindowManager.cs
+++ b/Infrastructure/WindowManager.cs
@@ -80,16 +80,21 @@ public static IWindowContext CreateWindow(RegisteredWindows.WindowKey windowKey,
return result;
}
- public static IWindowContext GetCreatedWindowContext(object viewModel)
+ public static IWindowContext GetWindowContext(object viewModel)
{
return createdWindowContexts.FirstOrDefault(windowContext => ReferenceEquals(windowContext.DataContext, viewModel));
}
+ public static void ShowMessageBox(string title, string text)
+ {
+ MessageBox.Show(text, title);
+ }
+
public static OpenFileDialogResult ShowOpenFileDialog(OpenFileDialogParameters openFileDialogParameters)
{
if (openFileDialogParameters == null)
{
- throw new ArgumentNullException("openFileDialogParameters");
+ throw new ArgumentNullException(nameof(openFileDialogParameters));
}
OpenFileDialog openFileDialog = new OpenFileDialog();
if (!String.IsNullOrEmpty(openFileDialogParameters.DialogTitle))
@@ -111,6 +116,36 @@ public static OpenFileDialogResult ShowOpenFileDialog(OpenFileDialogParameters o
return result;
}
+ public static SaveFileDialogResult ShowSaveFileDialog(SaveFileDialogParameters saveFileDialogParameters)
+ {
+ if (saveFileDialogParameters == null)
+ {
+ throw new ArgumentNullException(nameof(saveFileDialogParameters));
+ }
+ SaveFileDialog saveFileDialog = new SaveFileDialog();
+ if (!String.IsNullOrEmpty(saveFileDialogParameters.DialogTitle))
+ {
+ saveFileDialog.Title = saveFileDialogParameters.DialogTitle;
+ }
+ if (!String.IsNullOrEmpty(saveFileDialogParameters.Filter))
+ {
+ saveFileDialog.Filter = saveFileDialogParameters.Filter;
+ }
+ saveFileDialog.OverwritePrompt = saveFileDialogParameters.OverwritePrompt;
+ if (!String.IsNullOrEmpty(saveFileDialogParameters.InitialDirectory))
+ {
+ saveFileDialog.InitialDirectory = saveFileDialogParameters.InitialDirectory;
+ }
+ if (!String.IsNullOrEmpty(saveFileDialogParameters.InitialFileName))
+ {
+ saveFileDialog.FileName = saveFileDialogParameters.InitialFileName;
+ }
+ SaveFileDialogResult result = new SaveFileDialogResult();
+ result.DialogResult = saveFileDialog.ShowDialog() == true;
+ result.SelectedFilePath = result.DialogResult ? saveFileDialog.FileName : null;
+ return result;
+ }
+
public static void RemoveWindowMaximizeButton(Window window)
{
RemoveWindowStyle(window, WS_MAXIMIZEBOX);
@@ -131,18 +166,18 @@ public static void RemoveWindowIcon(Window window)
SetWindowPos(windowHandle, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
}
- private static void WindowContext_Closed(object sender, EventArgs e)
- {
- WindowContext closedWindowContext = (WindowContext)sender;
- createdWindowContexts.Remove(closedWindowContext);
- closedWindowContext.Closed -= WindowContext_Closed;
- }
-
private static void RemoveWindowStyle(Window window, int styleAttribute)
{
IntPtr windowHandle = new WindowInteropHelper(window).Handle;
int windowStyle = GetWindowLong(windowHandle, GWL_STYLE);
SetWindowLong(windowHandle, GWL_STYLE, windowStyle & ~styleAttribute);
}
+
+ private static void WindowContext_Closed(object sender, EventArgs e)
+ {
+ WindowContext closedWindowContext = (WindowContext)sender;
+ createdWindowContexts.Remove(closedWindowContext);
+ closedWindowContext.Closed -= WindowContext_Closed;
+ }
}
}
diff --git a/LibgenDesktop.csproj b/LibgenDesktop.csproj
index b611561..9be2ad1 100644
--- a/LibgenDesktop.csproj
+++ b/LibgenDesktop.csproj
@@ -42,6 +42,9 @@
packages\Costura.Fody.1.6.2\lib\dotnet\Costura.dll
False
+
+ packages\Dragablz.0.0.3.197\lib\net45\Dragablz.dll
+
packages\MaterialDesignColors.1.1.2\lib\net45\MaterialDesignColors.dll
@@ -51,14 +54,16 @@
packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll
-
- packages\SharpCompress.0.18.2\lib\net45\SharpCompress.dll
+
+ packages\SharpCompress.0.19.2\lib\net45\SharpCompress.dll
packages\System.Data.SQLite.Core.1.0.106.0\lib\net45\System.Data.SQLite.dll
+
+
@@ -78,39 +83,126 @@
Designer
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
-
-
- BookDetailsWindow.xaml
+
+
+
+
+
+
+
+
+ AddTabButton.xaml
+
+
+ CloseTabButton.xaml
+
+
+
+ SciMagDetailsWindow.xaml
+
+
+ FictionDetailsWindow.xaml
+
+
+ NonFictionDetailsWindow.xaml
BookAttributeValueLabel.xaml
+
+
+ PressedSwitch.xaml
+
+
+ SettingsTab.xaml
+
+
+ Toolbar.xaml
+
+
+ CreateDatabaseWindow.xaml
+
ErrorWindow.xaml
-
- SqlDumpImportWindow.xaml
+
+ ImportWindow.xaml
+
+
+ SciMagSearchResultsTab.xaml
+
+
+ FictionSearchResultsTab.xaml
+
+
+ NonFictionSearchResultsTab.xaml
+
+
+ DownloadManagerTab.xaml
+
+
+ SearchTab.xaml
+
+
+ SettingsWindow.xaml
-
+
+
+ MSBuild:Compile
+ Designer
+
+
+ Designer
+ MSBuild:Compile
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
Designer
MSBuild:Compile
@@ -118,10 +210,30 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
MSBuild:Compile
Designer
@@ -132,9 +244,8 @@
-
+
-
@@ -146,11 +257,63 @@
MainWindow.xaml
Code
-
+
+ MSBuild:Compile
Designer
+
+
MSBuild:Compile
+ Designer
-
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ Designer
+ MSBuild:Compile
+
+
+ MSBuild:Compile
+ Designer
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
Designer
MSBuild:Compile
@@ -162,11 +325,27 @@
Designer
MSBuild:Compile
+
+ MSBuild:Compile
+ Designer
+
Designer
MSBuild:Compile
-
+
+ Designer
+ MSBuild:Compile
+
+
+ MSBuild:Compile
+ Designer
+
+
+ Designer
+ MSBuild:Compile
+
+
Designer
MSBuild:Compile
@@ -212,7 +391,9 @@
-
+
+
+
diff --git a/Models/Database/LocalDatabase.cs b/Models/Database/LocalDatabase.cs
index 353fa38..0f9f7de 100644
--- a/Models/Database/LocalDatabase.cs
+++ b/Models/Database/LocalDatabase.cs
@@ -4,195 +4,150 @@
using System.Data.SQLite;
using System.Globalization;
using System.IO;
+using System.Runtime.CompilerServices;
using LibgenDesktop.Models.Entities;
namespace LibgenDesktop.Models.Database
{
- internal class LocalDatabase
+ internal class LocalDatabase : IDisposable
{
- private readonly SQLiteConnection connection;
+ private SQLiteConnection connection;
+ private bool disposed;
- public LocalDatabase(string databaseFileName)
+ private LocalDatabase(string databaseFilePath)
{
- if (!File.Exists(databaseFileName))
- {
- SQLiteConnection.CreateFile(databaseFileName);
- }
- connection = new SQLiteConnection("Data Source = " + databaseFileName);
+ disposed = false;
+ connection = new SQLiteConnection("Data Source = " + databaseFilePath);
connection.Open();
connection.EnableExtensions(true);
connection.LoadExtension("SQLite.Interop.dll", "sqlite3_fts5_init");
- using (SQLiteCommand command = connection.CreateCommand())
- {
- command.CommandText = SqlScripts.CREATE_BOOKS_TABLE;
- command.ExecuteNonQuery();
- }
- using (SQLiteCommand command = connection.CreateCommand())
+ ExecuteCommands("PRAGMA LOCKING_MODE = EXCLUSIVE", "PRAGMA TEMP_STORE = MEMORY", "PRAGMA JOURNAL_MODE = OFF",
+ "PRAGMA SYNCHRONOUS = OFF");
+ }
+
+ public static LocalDatabase CreateDatabase(string databaseFilePath)
+ {
+ SQLiteConnection.CreateFile(databaseFilePath);
+ return new LocalDatabase(databaseFilePath);
+ }
+
+ public static LocalDatabase OpenDatabase(string databaseFilePath)
+ {
+ if (!File.Exists(databaseFilePath))
{
- command.CommandText = SqlScripts.CREATE_BOOKS_FTS_TABLE;
- command.ExecuteNonQuery();
+ throw new FileNotFoundException("Database file not found", databaseFilePath);
}
- ExecuteCommands("PRAGMA LOCKING_MODE = EXCLUSIVE");
+ return new LocalDatabase(databaseFilePath);
}
- public int CountBooks()
+ public void Dispose()
{
- using (SQLiteCommand command = connection.CreateCommand())
+ if (!disposed && connection != null)
{
- command.CommandText = SqlScripts.COUNT_BOOKS;
- object objectResult = command.ExecuteScalar();
- return objectResult != DBNull.Value ? (int)(long)objectResult : 0;
+ connection.Dispose();
+ connection = null;
}
+ disposed = true;
}
- public IEnumerable GetAllBooks()
+ public void CreateMetadataTable()
{
+ ExecuteCommands(SqlScripts.CREATE_METADATA_TABLE);
+ }
+
+ public bool CheckIfMetadataExists()
+ {
+ return ExecuteScalarCommand(SqlScripts.CHECK_IF_METADATA_TABLE_EXIST) == 1;
+ }
+
+ public DatabaseMetadata GetMetadata()
+ {
+ DatabaseMetadata result = new DatabaseMetadata();
using (SQLiteCommand command = connection.CreateCommand())
{
- command.CommandText = SqlScripts.GET_ALL_BOOKS;
+ command.CommandText = SqlScripts.GET_ALL_METADATA_ITEMS;
using (SQLiteDataReader dataReader = command.ExecuteReader())
{
while (dataReader.Read())
{
- Book book = new Book();
- book.Id = dataReader.GetInt32(0);
- book.Title = dataReader.GetString(1);
- book.Authors = dataReader.GetString(2);
- book.Series = dataReader.GetString(3);
- book.Year = dataReader.GetString(4);
- book.Publisher = dataReader.GetString(5);
- book.Format = dataReader.GetString(6);
- book.SizeInBytes = dataReader.GetInt64(7);
- book.Searchable = dataReader.GetString(8);
- yield return book;
+ string key = dataReader.GetString(0);
+ string value = dataReader.GetString(1);
+ if (DatabaseMetadata.FieldDefinitions.TryGetValue(key.ToLower(), out DatabaseMetadata.FieldDefinition field))
+ {
+ field.Setter(result, value);
+ }
}
}
}
+ return result;
}
- public Book GetBookById(int id)
+ public void AddMetadata(DatabaseMetadata databaseMetadata)
+ {
+ foreach (DatabaseMetadata.FieldDefinition fieldDefinition in DatabaseMetadata.FieldDefinitions.Values)
+ {
+ using (SQLiteCommand command = connection.CreateCommand())
+ {
+ command.CommandText = SqlScripts.INSERT_METADATA_ITEM;
+ command.Parameters.AddWithValue("Key", fieldDefinition.FieldName);
+ command.Parameters.AddWithValue("Value", fieldDefinition.Getter(databaseMetadata));
+ command.ExecuteNonQuery();
+ }
+ }
+ }
+
+ public void CreateNonFictionTables()
+ {
+ ExecuteCommands(SqlScripts.CREATE_NON_FICTION_TABLE);
+ ExecuteCommands(SqlScripts.CREATE_NON_FICTION_FTS_TABLE);
+ }
+
+ public int CountNonFictionBooks()
+ {
+ return ExecuteScalarCommand(SqlScripts.COUNT_NON_FICTION);
+ }
+
+ public NonFictionBook GetNonFictionBookById(int id)
{
using (SQLiteCommand command = connection.CreateCommand())
{
- command.CommandText = SqlScripts.GET_BOOK_BY_ID;
+ command.CommandText = SqlScripts.GET_NON_FICTION_BY_ID;
command.Parameters.AddWithValue("@Id", id);
using (SQLiteDataReader dataReader = command.ExecuteReader())
{
dataReader.Read();
- Book book = new Book();
- book.ExtendedProperties = new Book.BookExtendedProperties();
- book.Id = dataReader.GetInt32(0);
- book.Title = dataReader.GetString(1);
- book.ExtendedProperties.VolumeInfo = dataReader.GetString(2);
- book.Series = dataReader.GetString(3);
- book.ExtendedProperties.Periodical = dataReader.GetString(4);
- book.Authors = dataReader.GetString(5);
- book.Year = dataReader.GetString(6);
- book.ExtendedProperties.Edition = dataReader.GetString(7);
- book.Publisher = dataReader.GetString(8);
- book.ExtendedProperties.City = dataReader.GetString(9);
- book.ExtendedProperties.Pages = dataReader.GetString(10);
- book.ExtendedProperties.PagesInFile = dataReader.GetInt32(11);
- book.ExtendedProperties.Language = dataReader.GetString(12);
- book.ExtendedProperties.Topic = dataReader.GetString(13);
- book.ExtendedProperties.Library = dataReader.GetString(14);
- book.ExtendedProperties.Issue = dataReader.GetString(15);
- book.ExtendedProperties.Identifier = dataReader.GetString(16);
- book.ExtendedProperties.Issn = dataReader.GetString(17);
- book.ExtendedProperties.Asin = dataReader.GetString(18);
- book.ExtendedProperties.Udc = dataReader.GetString(19);
- book.ExtendedProperties.Lbc = dataReader.GetString(20);
- book.ExtendedProperties.Ddc = dataReader.GetString(21);
- book.ExtendedProperties.Lcc = dataReader.GetString(22);
- book.ExtendedProperties.Doi = dataReader.GetString(23);
- book.ExtendedProperties.GoogleBookid = dataReader.GetString(24);
- book.ExtendedProperties.OpenLibraryId = dataReader.GetString(25);
- book.ExtendedProperties.Commentary = dataReader.GetString(26);
- book.ExtendedProperties.Dpi = dataReader.GetInt32(27);
- book.ExtendedProperties.Color = dataReader.GetString(28);
- book.ExtendedProperties.Cleaned = dataReader.GetString(29);
- book.ExtendedProperties.Orientation = dataReader.GetString(30);
- book.ExtendedProperties.Paginated = dataReader.GetString(31);
- book.ExtendedProperties.Scanned = dataReader.GetString(32);
- book.ExtendedProperties.Bookmarked = dataReader.GetString(33);
- book.Searchable = dataReader.GetString(34);
- book.SizeInBytes = dataReader.GetInt64(35);
- book.Format = dataReader.GetString(36);
- book.ExtendedProperties.Md5Hash = dataReader.GetString(37);
- book.ExtendedProperties.Generic = dataReader.GetString(38);
- book.ExtendedProperties.Visible = dataReader.GetString(39);
- book.ExtendedProperties.Locator = dataReader.GetString(40);
- book.ExtendedProperties.Local = dataReader.GetInt32(41);
- book.ExtendedProperties.AddedDateTime = DateTime.ParseExact(dataReader.GetString(42), "s", CultureInfo.InvariantCulture);
- book.ExtendedProperties.LastModifiedDateTime = DateTime.ParseExact(dataReader.GetString(43), "s", CultureInfo.InvariantCulture);
- book.ExtendedProperties.CoverUrl = dataReader.GetString(44);
- book.ExtendedProperties.Tags = dataReader.GetString(45);
- book.ExtendedProperties.IdentifierPlain = dataReader.GetString(46);
- book.ExtendedProperties.LibgenId = dataReader.GetInt32(47);
+ NonFictionBook book = ReadNonFictionBook(dataReader);
return book;
}
}
}
- public IEnumerable SearchBooks(string searchQuery)
+ public IEnumerable SearchNonFictionBooks(string searchQuery, int? resultLimit)
{
- List searchQueryBuilder = new List();
- foreach (string searchQueryPart in searchQuery.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))
- {
- switch (searchQueryPart)
- {
- case "AND":
- case "OR":
- case "NOT":
- searchQueryBuilder.Add(searchQueryPart);
- continue;
- default:
- if (searchQueryPart.Length > 1 && searchQueryPart.EndsWith("*"))
- {
- searchQueryBuilder.Add($"\"{ searchQueryPart.Substring(0, searchQueryPart.Length - 1) }\"*");
- }
- else
- {
- searchQueryBuilder.Add($"\"{ searchQueryPart }\"");
- }
- break;
- }
- }
- searchQuery = String.Join(" ", searchQueryBuilder);
+ searchQuery = EscapeSearchQuery(searchQuery);
using (SQLiteCommand command = connection.CreateCommand())
{
- command.CommandText = SqlScripts.SEARCH_BOOKS;
+ command.CommandText = GetSearchCommandWithLimit(SqlScripts.SEARCH_NON_FICTION, resultLimit);
command.Parameters.AddWithValue("@SearchQuery", searchQuery);
using (SQLiteDataReader dataReader = command.ExecuteReader())
{
while (dataReader.Read())
{
- Book book = new Book();
- book.Id = dataReader.GetInt32(0);
- book.Title = dataReader.GetString(1);
- book.Authors = dataReader.GetString(2);
- book.Series = dataReader.GetString(3);
- book.Year = dataReader.GetString(4);
- book.Publisher = dataReader.GetString(5);
- book.Format = dataReader.GetString(6);
- book.SizeInBytes = dataReader.GetInt64(7);
- book.Searchable = dataReader.GetString(8);
+ NonFictionBook book = ReadNonFictionBook(dataReader);
yield return book;
}
}
}
}
- public void AddBooks(List books)
+ public void AddNonFictionBooks(List books)
{
- ExecuteCommands("PRAGMA TEMP_STORE = MEMORY", "PRAGMA JOURNAL_MODE = OFF",
- "PRAGMA SYNCHRONOUS = OFF");
using (SQLiteTransaction transaction = connection.BeginTransaction())
{
using (SQLiteCommand insertCommand = connection.CreateCommand())
using (SQLiteCommand insertFtsCommand = connection.CreateCommand())
{
- insertCommand.CommandText = SqlScripts.INSERT_BOOK;
+ insertCommand.CommandText = SqlScripts.INSERT_NON_FICTION;
insertCommand.Parameters.AddWithValue("@Id", null);
SQLiteParameter titleParameter = insertCommand.Parameters.Add("@Title", DbType.String);
SQLiteParameter volumeInfoParameter = insertCommand.Parameters.Add("@VolumeInfo", DbType.String);
@@ -217,7 +172,7 @@ public void AddBooks(List books)
SQLiteParameter ddcParameter = insertCommand.Parameters.Add("@Ddc", DbType.String);
SQLiteParameter lccParameter = insertCommand.Parameters.Add("@Lcc", DbType.String);
SQLiteParameter doiParameter = insertCommand.Parameters.Add("@Doi", DbType.String);
- SQLiteParameter googleBookidParameter = insertCommand.Parameters.Add("@GoogleBookid", DbType.String);
+ SQLiteParameter googleBookIdParameter = insertCommand.Parameters.Add("@GoogleBookId", DbType.String);
SQLiteParameter openLibraryIdParameter = insertCommand.Parameters.Add("@OpenLibraryId", DbType.String);
SQLiteParameter commentaryParameter = insertCommand.Parameters.Add("@Commentary", DbType.String);
SQLiteParameter dpiParameter = insertCommand.Parameters.Add("@Dpi", DbType.Int32);
@@ -241,74 +196,611 @@ public void AddBooks(List books)
SQLiteParameter tagsParameter = insertCommand.Parameters.Add("@Tags", DbType.String);
SQLiteParameter identifierPlainParameter = insertCommand.Parameters.Add("@IdentifierPlain", DbType.String);
SQLiteParameter libgenIdParameter = insertCommand.Parameters.Add("@LibgenId", DbType.Int32);
- insertFtsCommand.CommandText = SqlScripts.INSERT_BOOK_FTS;
+ insertFtsCommand.CommandText = SqlScripts.INSERT_NON_FICTION_FTS;
SQLiteParameter titleFtsParameter = insertFtsCommand.Parameters.Add("@Title", DbType.String);
SQLiteParameter seriesFtsParameter = insertFtsCommand.Parameters.Add("@Series", DbType.String);
SQLiteParameter authorsFtsParameter = insertFtsCommand.Parameters.Add("@Authors", DbType.String);
SQLiteParameter publisherFtsParameter = insertFtsCommand.Parameters.Add("@Publisher", DbType.String);
SQLiteParameter identifierPlainFtsParameter = insertFtsCommand.Parameters.Add("@IdentifierPlain", DbType.String);
- foreach (Book book in books)
+ foreach (NonFictionBook book in books)
{
titleParameter.Value = book.Title;
- volumeInfoParameter.Value = book.ExtendedProperties.VolumeInfo;
+ volumeInfoParameter.Value = book.VolumeInfo;
seriesParameter.Value = book.Series;
- periodicalParameter.Value = book.ExtendedProperties.Periodical;
+ periodicalParameter.Value = book.Periodical;
authorsParameter.Value = book.Authors;
yearParameter.Value = book.Year;
- editionParameter.Value = book.ExtendedProperties.Edition;
+ editionParameter.Value = book.Edition;
publisherParameter.Value = book.Publisher;
- cityParameter.Value = book.ExtendedProperties.City;
- pagesParameter.Value = book.ExtendedProperties.Pages;
- pagesInFileParameter.Value = book.ExtendedProperties.PagesInFile;
- languageParameter.Value = book.ExtendedProperties.Language;
- topicParameter.Value = book.ExtendedProperties.Topic;
- libraryParameter.Value = book.ExtendedProperties.Library;
- issueParameter.Value = book.ExtendedProperties.Issue;
- identifierParameter.Value = book.ExtendedProperties.Identifier;
- issnParameter.Value = book.ExtendedProperties.Issn;
- asinParameter.Value = book.ExtendedProperties.Asin;
- udcParameter.Value = book.ExtendedProperties.Udc;
- lbcParameter.Value = book.ExtendedProperties.Lbc;
- ddcParameter.Value = book.ExtendedProperties.Ddc;
- lccParameter.Value = book.ExtendedProperties.Lcc;
- doiParameter.Value = book.ExtendedProperties.Doi;
- googleBookidParameter.Value = book.ExtendedProperties.GoogleBookid;
- openLibraryIdParameter.Value = book.ExtendedProperties.OpenLibraryId;
- commentaryParameter.Value = book.ExtendedProperties.Commentary;
- dpiParameter.Value = book.ExtendedProperties.Dpi;
- colorParameter.Value = book.ExtendedProperties.Color;
- cleanedParameter.Value = book.ExtendedProperties.Cleaned;
- orientationParameter.Value = book.ExtendedProperties.Orientation;
- paginatedParameter.Value = book.ExtendedProperties.Paginated;
- scannedParameter.Value = book.ExtendedProperties.Scanned;
- bookmarkedParameter.Value = book.ExtendedProperties.Bookmarked;
+ cityParameter.Value = book.City;
+ pagesParameter.Value = book.Pages;
+ pagesInFileParameter.Value = book.PagesInFile;
+ languageParameter.Value = book.Language;
+ topicParameter.Value = book.Topic;
+ libraryParameter.Value = book.Library;
+ issueParameter.Value = book.Issue;
+ identifierParameter.Value = book.Identifier;
+ issnParameter.Value = book.Issn;
+ asinParameter.Value = book.Asin;
+ udcParameter.Value = book.Udc;
+ lbcParameter.Value = book.Lbc;
+ ddcParameter.Value = book.Ddc;
+ lccParameter.Value = book.Lcc;
+ doiParameter.Value = book.Doi;
+ googleBookIdParameter.Value = book.GoogleBookId;
+ openLibraryIdParameter.Value = book.OpenLibraryId;
+ commentaryParameter.Value = book.Commentary;
+ dpiParameter.Value = book.Dpi;
+ colorParameter.Value = book.Color;
+ cleanedParameter.Value = book.Cleaned;
+ orientationParameter.Value = book.Orientation;
+ paginatedParameter.Value = book.Paginated;
+ scannedParameter.Value = book.Scanned;
+ bookmarkedParameter.Value = book.Bookmarked;
searchableParameter.Value = book.Searchable;
sizeInBytesParameter.Value = book.SizeInBytes;
formatParameter.Value = book.Format;
- md5HashParameter.Value = book.ExtendedProperties.Md5Hash;
- genericParameter.Value = book.ExtendedProperties.Generic;
- visibleParameter.Value = book.ExtendedProperties.Visible;
- locatorParameter.Value = book.ExtendedProperties.Locator;
- localParameter.Value = book.ExtendedProperties.Local;
- addedDateTimeParameter.Value = book.ExtendedProperties.AddedDateTime.ToString("s");
- lastModifiedDateTimeParameter.Value = book.ExtendedProperties.LastModifiedDateTime.ToString("s");
- coverUrlParameter.Value = book.ExtendedProperties.CoverUrl;
- tagsParameter.Value = book.ExtendedProperties.Tags;
- identifierPlainParameter.Value = book.ExtendedProperties.IdentifierPlain;
- libgenIdParameter.Value = book.ExtendedProperties.LibgenId;
+ md5HashParameter.Value = book.Md5Hash;
+ genericParameter.Value = book.Generic;
+ visibleParameter.Value = book.Visible;
+ locatorParameter.Value = book.Locator;
+ localParameter.Value = book.Local;
+ addedDateTimeParameter.Value = book.AddedDateTime.ToString("s");
+ lastModifiedDateTimeParameter.Value = book.LastModifiedDateTime.ToString("s");
+ coverUrlParameter.Value = book.CoverUrl;
+ tagsParameter.Value = book.Tags;
+ identifierPlainParameter.Value = book.IdentifierPlain;
+ libgenIdParameter.Value = book.LibgenId;
insertCommand.ExecuteNonQuery();
titleFtsParameter.Value = book.Title;
seriesFtsParameter.Value = book.Series;
authorsFtsParameter.Value = book.Authors;
publisherFtsParameter.Value = book.Publisher;
- identifierPlainFtsParameter.Value = book.ExtendedProperties.IdentifierPlain;
+ identifierPlainFtsParameter.Value = book.IdentifierPlain;
+ insertFtsCommand.ExecuteNonQuery();
+ }
+ }
+ transaction.Commit();
+ }
+ }
+
+ public void CreateFictionTables()
+ {
+ ExecuteCommands(SqlScripts.CREATE_FICTION_TABLE);
+ ExecuteCommands(SqlScripts.CREATE_FICTION_FTS_TABLE);
+ }
+
+ public int CountFictionBooks()
+ {
+ return ExecuteScalarCommand(SqlScripts.COUNT_FICTION);
+ }
+
+ public FictionBook GetFictionBookById(int id)
+ {
+ using (SQLiteCommand command = connection.CreateCommand())
+ {
+ command.CommandText = SqlScripts.GET_FICTION_BY_ID;
+ command.Parameters.AddWithValue("@Id", id);
+ using (SQLiteDataReader dataReader = command.ExecuteReader())
+ {
+ dataReader.Read();
+ FictionBook book = ReadFictionBook(dataReader);
+ return book;
+ }
+ }
+ }
+
+ public IEnumerable SearchFictionBooks(string searchQuery, int? resultLimit)
+ {
+ searchQuery = EscapeSearchQuery(searchQuery);
+ using (SQLiteCommand command = connection.CreateCommand())
+ {
+ command.CommandText = GetSearchCommandWithLimit(SqlScripts.SEARCH_FICTION, resultLimit);
+ command.Parameters.AddWithValue("@SearchQuery", searchQuery);
+ using (SQLiteDataReader dataReader = command.ExecuteReader())
+ {
+ while (dataReader.Read())
+ {
+ FictionBook book = ReadFictionBook(dataReader);
+ yield return book;
+ }
+ }
+ }
+ }
+
+ public void AddFictionBooks(List books)
+ {
+ using (SQLiteTransaction transaction = connection.BeginTransaction())
+ {
+ using (SQLiteCommand insertCommand = connection.CreateCommand())
+ using (SQLiteCommand insertFtsCommand = connection.CreateCommand())
+ {
+ insertCommand.CommandText = SqlScripts.INSERT_FICTION;
+ insertCommand.Parameters.AddWithValue("@Id", null);
+ SQLiteParameter authorFamily1Parameter = insertCommand.Parameters.Add("@AuthorFamily1", DbType.String);
+ SQLiteParameter authorName1Parameter = insertCommand.Parameters.Add("@AuthorName1", DbType.String);
+ SQLiteParameter authorSurname1Parameter = insertCommand.Parameters.Add("@AuthorSurname1", DbType.String);
+ SQLiteParameter role1Parameter = insertCommand.Parameters.Add("@Role1", DbType.String);
+ SQLiteParameter pseudonim1Parameter = insertCommand.Parameters.Add("@Pseudonim1", DbType.String);
+ SQLiteParameter authorFamily2Parameter = insertCommand.Parameters.Add("@AuthorFamily2", DbType.String);
+ SQLiteParameter authorName2Parameter = insertCommand.Parameters.Add("@AuthorName2", DbType.String);
+ SQLiteParameter authorSurname2Parameter = insertCommand.Parameters.Add("@AuthorSurname2", DbType.String);
+ SQLiteParameter role2Parameter = insertCommand.Parameters.Add("@Role2", DbType.String);
+ SQLiteParameter pseudonim2Parameter = insertCommand.Parameters.Add("@Pseudonim2", DbType.String);
+ SQLiteParameter authorFamily3Parameter = insertCommand.Parameters.Add("@AuthorFamily3", DbType.String);
+ SQLiteParameter authorName3Parameter = insertCommand.Parameters.Add("@AuthorName3", DbType.String);
+ SQLiteParameter authorSurname3Parameter = insertCommand.Parameters.Add("@AuthorSurname3", DbType.String);
+ SQLiteParameter role3Parameter = insertCommand.Parameters.Add("@Role3", DbType.String);
+ SQLiteParameter pseudonim3Parameter = insertCommand.Parameters.Add("@Pseudonim3", DbType.String);
+ SQLiteParameter authorFamily4Parameter = insertCommand.Parameters.Add("@AuthorFamily4", DbType.String);
+ SQLiteParameter authorName4Parameter = insertCommand.Parameters.Add("@AuthorName4", DbType.String);
+ SQLiteParameter authorSurname4Parameter = insertCommand.Parameters.Add("@AuthorSurname4", DbType.String);
+ SQLiteParameter role4Parameter = insertCommand.Parameters.Add("@Role4", DbType.String);
+ SQLiteParameter pseudonim4Parameter = insertCommand.Parameters.Add("@Pseudonim4", DbType.String);
+ SQLiteParameter series1Parameter = insertCommand.Parameters.Add("@Series1", DbType.String);
+ SQLiteParameter series2Parameter = insertCommand.Parameters.Add("@Series2", DbType.String);
+ SQLiteParameter series3Parameter = insertCommand.Parameters.Add("@Series3", DbType.String);
+ SQLiteParameter series4Parameter = insertCommand.Parameters.Add("@Series4", DbType.String);
+ SQLiteParameter titleParameter = insertCommand.Parameters.Add("@Title", DbType.String);
+ SQLiteParameter formatParameter = insertCommand.Parameters.Add("@Format", DbType.String);
+ SQLiteParameter versionParameter = insertCommand.Parameters.Add("@Version", DbType.String);
+ SQLiteParameter sizeInBytesParameter = insertCommand.Parameters.Add("@SizeInBytes", DbType.Int64);
+ SQLiteParameter md5HashParameter = insertCommand.Parameters.Add("@Md5Hash", DbType.String);
+ SQLiteParameter pathParameter = insertCommand.Parameters.Add("@Path", DbType.String);
+ SQLiteParameter languageParameter = insertCommand.Parameters.Add("@Language", DbType.String);
+ SQLiteParameter pagesParameter = insertCommand.Parameters.Add("@Pages", DbType.String);
+ SQLiteParameter identifierParameter = insertCommand.Parameters.Add("@Identifier", DbType.String);
+ SQLiteParameter yearParameter = insertCommand.Parameters.Add("@Year", DbType.String);
+ SQLiteParameter publisherParameter = insertCommand.Parameters.Add("@Publisher", DbType.String);
+ SQLiteParameter editionParameter = insertCommand.Parameters.Add("@Edition", DbType.String);
+ SQLiteParameter commentaryParameter = insertCommand.Parameters.Add("@Commentary", DbType.String);
+ SQLiteParameter addedDateTimeParameter = insertCommand.Parameters.Add("@AddedDateTime", DbType.String);
+ SQLiteParameter lastModifiedDateTimeParameter = insertCommand.Parameters.Add("@LastModifiedDateTime", DbType.String);
+ SQLiteParameter russianAuthorFamilyParameter = insertCommand.Parameters.Add("@RussianAuthorFamily", DbType.String);
+ SQLiteParameter russianAuthorNameParameter = insertCommand.Parameters.Add("@RussianAuthorName", DbType.String);
+ SQLiteParameter russianAuthorSurnameParameter = insertCommand.Parameters.Add("@RussianAuthorSurname", DbType.String);
+ SQLiteParameter coverParameter = insertCommand.Parameters.Add("@Cover", DbType.String);
+ SQLiteParameter googleBookIdParameter = insertCommand.Parameters.Add("@GoogleBookId", DbType.String);
+ SQLiteParameter asinParameter = insertCommand.Parameters.Add("@Asin", DbType.String);
+ SQLiteParameter authorHashParameter = insertCommand.Parameters.Add("@AuthorHash", DbType.String);
+ SQLiteParameter titleHashParameter = insertCommand.Parameters.Add("@TitleHash", DbType.String);
+ SQLiteParameter visibleParameter = insertCommand.Parameters.Add("@Visible", DbType.String);
+ SQLiteParameter libgenIdParameter = insertCommand.Parameters.Add("@LibgenId", DbType.Int32);
+ insertFtsCommand.CommandText = SqlScripts.INSERT_FICTION_FTS;
+ SQLiteParameter titleFtsParameter = insertFtsCommand.Parameters.Add("@Title", DbType.String);
+ SQLiteParameter authorFamily1FtsParameter = insertFtsCommand.Parameters.Add("@AuthorFamily1", DbType.String);
+ SQLiteParameter authorName1FtsParameter = insertFtsCommand.Parameters.Add("@AuthorName1", DbType.String);
+ SQLiteParameter authorSurname1FtsParameter = insertFtsCommand.Parameters.Add("@AuthorSurname1", DbType.String);
+ SQLiteParameter pseudonim1FtsParameter = insertFtsCommand.Parameters.Add("@Pseudonim1", DbType.String);
+ SQLiteParameter authorFamily2FtsParameter = insertFtsCommand.Parameters.Add("@AuthorFamily2", DbType.String);
+ SQLiteParameter authorName2FtsParameter = insertFtsCommand.Parameters.Add("@AuthorName2", DbType.String);
+ SQLiteParameter authorSurname2FtsParameter = insertFtsCommand.Parameters.Add("@AuthorSurname2", DbType.String);
+ SQLiteParameter pseudonim2FtsParameter = insertFtsCommand.Parameters.Add("@Pseudonim2", DbType.String);
+ SQLiteParameter authorFamily3FtsParameter = insertFtsCommand.Parameters.Add("@AuthorFamily3", DbType.String);
+ SQLiteParameter authorName3FtsParameter = insertFtsCommand.Parameters.Add("@AuthorName3", DbType.String);
+ SQLiteParameter authorSurname3FtsParameter = insertFtsCommand.Parameters.Add("@AuthorSurname3", DbType.String);
+ SQLiteParameter pseudonim3FtsParameter = insertFtsCommand.Parameters.Add("@Pseudonim3", DbType.String);
+ SQLiteParameter authorFamily4FtsParameter = insertFtsCommand.Parameters.Add("@AuthorFamily4", DbType.String);
+ SQLiteParameter authorName4FtsParameter = insertFtsCommand.Parameters.Add("@AuthorName4", DbType.String);
+ SQLiteParameter authorSurname4FtsParameter = insertFtsCommand.Parameters.Add("@AuthorSurname4", DbType.String);
+ SQLiteParameter pseudonim4FtsParameter = insertFtsCommand.Parameters.Add("@Pseudonim4", DbType.String);
+ SQLiteParameter russianAuthorFamilyFtsParameter = insertFtsCommand.Parameters.Add("@RussianAuthorFamily", DbType.String);
+ SQLiteParameter russianAuthorNameFtsParameter = insertFtsCommand.Parameters.Add("@RussianAuthorName", DbType.String);
+ SQLiteParameter russianAuthorSurnameFtsParameter = insertFtsCommand.Parameters.Add("@RussianAuthorSurname", DbType.String);
+ SQLiteParameter series1FtsParameter = insertFtsCommand.Parameters.Add("@Series1", DbType.String);
+ SQLiteParameter series2FtsParameter = insertFtsCommand.Parameters.Add("@Series2", DbType.String);
+ SQLiteParameter series3FtsParameter = insertFtsCommand.Parameters.Add("@Series3", DbType.String);
+ SQLiteParameter series4FtsParameter = insertFtsCommand.Parameters.Add("@Series4", DbType.String);
+ SQLiteParameter publisherFtsParameter = insertFtsCommand.Parameters.Add("@Publisher", DbType.String);
+ SQLiteParameter identifierFtsParameter = insertFtsCommand.Parameters.Add("@Identifier", DbType.String);
+ foreach (FictionBook book in books)
+ {
+ authorFamily1Parameter.Value = book.AuthorFamily1;
+ authorName1Parameter.Value = book.AuthorName1;
+ authorSurname1Parameter.Value = book.AuthorSurname1;
+ role1Parameter.Value = book.Role1;
+ pseudonim1Parameter.Value = book.Pseudonim1;
+ authorFamily2Parameter.Value = book.AuthorFamily2;
+ authorName2Parameter.Value = book.AuthorName2;
+ authorSurname2Parameter.Value = book.AuthorSurname2;
+ role2Parameter.Value = book.Role2;
+ pseudonim2Parameter.Value = book.Pseudonim2;
+ authorFamily3Parameter.Value = book.AuthorFamily3;
+ authorName3Parameter.Value = book.AuthorName3;
+ authorSurname3Parameter.Value = book.AuthorSurname3;
+ role3Parameter.Value = book.Role3;
+ pseudonim3Parameter.Value = book.Pseudonim3;
+ authorFamily4Parameter.Value = book.AuthorFamily4;
+ authorName4Parameter.Value = book.AuthorName4;
+ authorSurname4Parameter.Value = book.AuthorSurname4;
+ role4Parameter.Value = book.Role4;
+ pseudonim4Parameter.Value = book.Pseudonim4;
+ series1Parameter.Value = book.Series1;
+ series2Parameter.Value = book.Series2;
+ series3Parameter.Value = book.Series3;
+ series4Parameter.Value = book.Series4;
+ titleParameter.Value = book.Title;
+ formatParameter.Value = book.Format;
+ versionParameter.Value = book.Version;
+ sizeInBytesParameter.Value = book.SizeInBytes;
+ md5HashParameter.Value = book.Md5Hash;
+ pathParameter.Value = book.Path;
+ languageParameter.Value = book.Language;
+ pagesParameter.Value = book.Pages;
+ identifierParameter.Value = book.Identifier;
+ yearParameter.Value = book.Year;
+ publisherParameter.Value = book.Publisher;
+ editionParameter.Value = book.Edition;
+ commentaryParameter.Value = book.Commentary;
+ addedDateTimeParameter.Value = book.AddedDateTime?.ToString("s");
+ lastModifiedDateTimeParameter.Value = book.LastModifiedDateTime.ToString("s");
+ russianAuthorFamilyParameter.Value = book.RussianAuthorFamily;
+ russianAuthorNameParameter.Value = book.RussianAuthorName;
+ russianAuthorSurnameParameter.Value = book.RussianAuthorSurname;
+ coverParameter.Value = book.Cover;
+ googleBookIdParameter.Value = book.GoogleBookId;
+ asinParameter.Value = book.Asin;
+ authorHashParameter.Value = book.AuthorHash;
+ titleHashParameter.Value = book.TitleHash;
+ visibleParameter.Value = book.Visible;
+ libgenIdParameter.Value = book.LibgenId;
+ insertCommand.ExecuteNonQuery();
+ titleFtsParameter.Value = book.Title;
+ authorFamily1FtsParameter.Value = book.AuthorFamily1;
+ authorName1FtsParameter.Value = book.AuthorName1;
+ authorSurname1FtsParameter.Value = book.AuthorSurname1;
+ pseudonim1FtsParameter.Value = book.Pseudonim1;
+ authorFamily2FtsParameter.Value = book.AuthorFamily2;
+ authorName2FtsParameter.Value = book.AuthorName2;
+ authorSurname2FtsParameter.Value = book.AuthorSurname2;
+ pseudonim2FtsParameter.Value = book.Pseudonim2;
+ authorFamily3FtsParameter.Value = book.AuthorFamily3;
+ authorName3FtsParameter.Value = book.AuthorName3;
+ authorSurname3FtsParameter.Value = book.AuthorSurname3;
+ pseudonim3FtsParameter.Value = book.Pseudonim3;
+ authorFamily4FtsParameter.Value = book.AuthorFamily4;
+ authorName4FtsParameter.Value = book.AuthorName4;
+ authorSurname4FtsParameter.Value = book.AuthorSurname4;
+ pseudonim4FtsParameter.Value = book.Pseudonim4;
+ russianAuthorFamilyFtsParameter.Value = book.RussianAuthorFamily;
+ russianAuthorNameFtsParameter.Value = book.RussianAuthorName;
+ russianAuthorSurnameFtsParameter.Value = book.RussianAuthorSurname;
+ series1FtsParameter.Value = book.Series1;
+ series2FtsParameter.Value = book.Series2;
+ series3FtsParameter.Value = book.Series3;
+ series4FtsParameter.Value = book.Series4;
+ publisherFtsParameter.Value = book.Publisher;
+ identifierFtsParameter.Value = book.Identifier;
insertFtsCommand.ExecuteNonQuery();
}
}
transaction.Commit();
}
- ExecuteCommands("PRAGMA TEMP_STORE = DEFAULT", "PRAGMA JOURNAL_MODE = DELETE",
- "PRAGMA SYNCHRONOUS = FULL");
+ }
+
+ public void CreateSciMagTables()
+ {
+ ExecuteCommands(SqlScripts.CREATE_SCIMAG_TABLE);
+ ExecuteCommands(SqlScripts.CREATE_SCIMAG_FTS_TABLE);
+ }
+
+ public int CountSciMagArticles()
+ {
+ return ExecuteScalarCommand(SqlScripts.COUNT_SCIMAG);
+ }
+
+ public SciMagArticle GetSciMagArticleById(int id)
+ {
+ using (SQLiteCommand command = connection.CreateCommand())
+ {
+ command.CommandText = SqlScripts.GET_SCIMAG_BY_ID;
+ command.Parameters.AddWithValue("@Id", id);
+ using (SQLiteDataReader dataReader = command.ExecuteReader())
+ {
+ dataReader.Read();
+ SciMagArticle article = ReadSciMagArticle(dataReader);
+ return article;
+ }
+ }
+ }
+
+ public IEnumerable SearchSciMagArticles(string searchQuery, int? resultLimit)
+ {
+ searchQuery = EscapeSearchQuery(searchQuery);
+ using (SQLiteCommand command = connection.CreateCommand())
+ {
+ command.CommandText = GetSearchCommandWithLimit(SqlScripts.SEARCH_SCIMAG, resultLimit);
+ command.Parameters.AddWithValue("@SearchQuery", searchQuery);
+ using (SQLiteDataReader dataReader = command.ExecuteReader())
+ {
+ while (dataReader.Read())
+ {
+ SciMagArticle article = ReadSciMagArticle(dataReader);
+ yield return article;
+ }
+ }
+ }
+ }
+
+ public void AddSciMagArticles(List articles)
+ {
+ using (SQLiteTransaction transaction = connection.BeginTransaction())
+ {
+ using (SQLiteCommand insertCommand = connection.CreateCommand())
+ using (SQLiteCommand insertFtsCommand = connection.CreateCommand())
+ {
+ insertCommand.CommandText = SqlScripts.INSERT_SCIMAG;
+ insertCommand.Parameters.AddWithValue("@Id", null);
+ SQLiteParameter doiParameter = insertCommand.Parameters.Add("@Doi", DbType.String);
+ SQLiteParameter doi2Parameter = insertCommand.Parameters.Add("@Doi2", DbType.String);
+ SQLiteParameter titleParameter = insertCommand.Parameters.Add("@Title", DbType.String);
+ SQLiteParameter authorsParameter = insertCommand.Parameters.Add("@Authors", DbType.String);
+ SQLiteParameter yearParameter = insertCommand.Parameters.Add("@Year", DbType.String);
+ SQLiteParameter monthParameter = insertCommand.Parameters.Add("@Month", DbType.String);
+ SQLiteParameter dayParameter = insertCommand.Parameters.Add("@Day", DbType.String);
+ SQLiteParameter volumeParameter = insertCommand.Parameters.Add("@Volume", DbType.String);
+ SQLiteParameter issueParameter = insertCommand.Parameters.Add("@Issue", DbType.String);
+ SQLiteParameter firstPageParameter = insertCommand.Parameters.Add("@FirstPage", DbType.String);
+ SQLiteParameter lastPageParameter = insertCommand.Parameters.Add("@LastPage", DbType.String);
+ SQLiteParameter journalParameter = insertCommand.Parameters.Add("@Journal", DbType.String);
+ SQLiteParameter isbnParameter = insertCommand.Parameters.Add("@Isbn", DbType.String);
+ SQLiteParameter issnpParameter = insertCommand.Parameters.Add("@Issnp", DbType.String);
+ SQLiteParameter issneParameter = insertCommand.Parameters.Add("@Issne", DbType.String);
+ SQLiteParameter md5HashParameter = insertCommand.Parameters.Add("@Md5Hash", DbType.String);
+ SQLiteParameter sizeInBytesParameter = insertCommand.Parameters.Add("@SizeInBytes", DbType.Int64);
+ SQLiteParameter addedDateTimeParameter = insertCommand.Parameters.Add("@AddedDateTime", DbType.String);
+ SQLiteParameter journalIdParameter = insertCommand.Parameters.Add("@JournalId", DbType.String);
+ SQLiteParameter abstractUrlParameter = insertCommand.Parameters.Add("@AbstractUrl", DbType.String);
+ SQLiteParameter attribute1Parameter = insertCommand.Parameters.Add("@Attribute1", DbType.String);
+ SQLiteParameter attribute2Parameter = insertCommand.Parameters.Add("@Attribute2", DbType.String);
+ SQLiteParameter attribute3Parameter = insertCommand.Parameters.Add("@Attribute3", DbType.String);
+ SQLiteParameter attribute4Parameter = insertCommand.Parameters.Add("@Attribute4", DbType.String);
+ SQLiteParameter attribute5Parameter = insertCommand.Parameters.Add("@Attribute5", DbType.String);
+ SQLiteParameter attribute6Parameter = insertCommand.Parameters.Add("@Attribute6", DbType.String);
+ SQLiteParameter visibleParameter = insertCommand.Parameters.Add("@Visible", DbType.String);
+ SQLiteParameter pubmedIdParameter = insertCommand.Parameters.Add("@PubmedId", DbType.String);
+ SQLiteParameter pmcParameter = insertCommand.Parameters.Add("@Pmc", DbType.String);
+ SQLiteParameter piiParameter = insertCommand.Parameters.Add("@Pii", DbType.String);
+ SQLiteParameter libgenIdParameter = insertCommand.Parameters.Add("@LibgenId", DbType.Int32);
+ insertFtsCommand.CommandText = SqlScripts.INSERT_SCIMAG_FTS;
+ SQLiteParameter titleFtsParameter = insertFtsCommand.Parameters.Add("@Title", DbType.String);
+ SQLiteParameter authorsFtsParameter = insertFtsCommand.Parameters.Add("@Authors", DbType.String);
+ SQLiteParameter doiFtsParameter = insertFtsCommand.Parameters.Add("@Doi", DbType.String);
+ SQLiteParameter doi2FtsParameter = insertFtsCommand.Parameters.Add("@Doi2", DbType.String);
+ SQLiteParameter pubmedIdFtsParameter = insertFtsCommand.Parameters.Add("@PubmedId", DbType.String);
+ SQLiteParameter journalFtsParameter = insertFtsCommand.Parameters.Add("@Journal", DbType.String);
+ SQLiteParameter issnpFtsParameter = insertFtsCommand.Parameters.Add("@Issnp", DbType.String);
+ SQLiteParameter issneFtsParameter = insertFtsCommand.Parameters.Add("@Issne", DbType.String);
+ foreach (SciMagArticle article in articles)
+ {
+ doiParameter.Value = article.Doi;
+ doi2Parameter.Value = article.Doi2;
+ titleParameter.Value = article.Title;
+ authorsParameter.Value = article.Authors;
+ yearParameter.Value = article.Year;
+ monthParameter.Value = article.Month;
+ dayParameter.Value = article.Day;
+ volumeParameter.Value = article.Volume;
+ issueParameter.Value = article.Issue;
+ firstPageParameter.Value = article.FirstPage;
+ lastPageParameter.Value = article.LastPage;
+ journalParameter.Value = article.Journal;
+ isbnParameter.Value = article.Isbn;
+ issnpParameter.Value = article.Issnp;
+ issneParameter.Value = article.Issne;
+ md5HashParameter.Value = article.Md5Hash;
+ sizeInBytesParameter.Value = article.SizeInBytes;
+ addedDateTimeParameter.Value = article.AddedDateTime?.ToString("s");
+ journalIdParameter.Value = article.JournalId;
+ abstractUrlParameter.Value = article.AbstractUrl;
+ attribute1Parameter.Value = article.Attribute1;
+ attribute2Parameter.Value = article.Attribute2;
+ attribute3Parameter.Value = article.Attribute3;
+ attribute4Parameter.Value = article.Attribute4;
+ attribute5Parameter.Value = article.Attribute5;
+ attribute6Parameter.Value = article.Attribute6;
+ visibleParameter.Value = article.Visible;
+ pubmedIdParameter.Value = article.PubmedId;
+ pmcParameter.Value = article.Pmc;
+ piiParameter.Value = article.Pii;
+ libgenIdParameter.Value = article.LibgenId;
+ insertCommand.ExecuteNonQuery();
+ titleFtsParameter.Value = article.Title;
+ authorsFtsParameter.Value = article.Authors;
+ doiFtsParameter.Value = article.Doi;
+ doi2FtsParameter.Value = article.Doi2;
+ pubmedIdFtsParameter.Value = article.PubmedId;
+ journalFtsParameter.Value = article.Journal;
+ issnpFtsParameter.Value = article.Issnp;
+ issneFtsParameter.Value = article.Issne;
+ insertFtsCommand.ExecuteNonQuery();
+ }
+ }
+ transaction.Commit();
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private NonFictionBook ReadNonFictionBook(SQLiteDataReader dataReader)
+ {
+ NonFictionBook book = new NonFictionBook();
+ book.Id = dataReader.GetInt32(0);
+ book.Title = dataReader.GetString(1);
+ book.VolumeInfo = dataReader.GetString(2);
+ book.Series = dataReader.GetString(3);
+ book.Periodical = dataReader.GetString(4);
+ book.Authors = dataReader.GetString(5);
+ book.Year = dataReader.GetString(6);
+ book.Edition = dataReader.GetString(7);
+ book.Publisher = dataReader.GetString(8);
+ book.City = dataReader.GetString(9);
+ book.Pages = dataReader.GetString(10);
+ book.PagesInFile = dataReader.GetInt32(11);
+ book.Language = dataReader.GetString(12);
+ book.Topic = dataReader.GetString(13);
+ book.Library = dataReader.GetString(14);
+ book.Issue = dataReader.GetString(15);
+ book.Identifier = dataReader.GetString(16);
+ book.Issn = dataReader.GetString(17);
+ book.Asin = dataReader.GetString(18);
+ book.Udc = dataReader.GetString(19);
+ book.Lbc = dataReader.GetString(20);
+ book.Ddc = dataReader.GetString(21);
+ book.Lcc = dataReader.GetString(22);
+ book.Doi = dataReader.GetString(23);
+ book.GoogleBookId = dataReader.GetString(24);
+ book.OpenLibraryId = dataReader.GetString(25);
+ book.Commentary = dataReader.GetString(26);
+ book.Dpi = dataReader.GetInt32(27);
+ book.Color = dataReader.GetString(28);
+ book.Cleaned = dataReader.GetString(29);
+ book.Orientation = dataReader.GetString(30);
+ book.Paginated = dataReader.GetString(31);
+ book.Scanned = dataReader.GetString(32);
+ book.Bookmarked = dataReader.GetString(33);
+ book.Searchable = dataReader.GetString(34);
+ book.SizeInBytes = dataReader.GetInt64(35);
+ book.Format = dataReader.GetString(36);
+ book.Md5Hash = dataReader.GetString(37);
+ book.Generic = dataReader.GetString(38);
+ book.Visible = dataReader.GetString(39);
+ book.Locator = dataReader.GetString(40);
+ book.Local = dataReader.GetInt32(41);
+ book.AddedDateTime = ParseDbDate(dataReader.GetString(42));
+ book.LastModifiedDateTime = ParseDbDate(dataReader.GetString(43));
+ book.CoverUrl = dataReader.GetString(44);
+ book.Tags = dataReader.GetString(45);
+ book.IdentifierPlain = dataReader.GetString(46);
+ book.LibgenId = dataReader.GetInt32(47);
+ return book;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private FictionBook ReadFictionBook(SQLiteDataReader dataReader)
+ {
+ FictionBook book = new FictionBook();
+ book.Id = dataReader.GetInt32(0);
+ book.AuthorFamily1 = dataReader.GetString(1);
+ book.AuthorName1 = dataReader.GetString(2);
+ book.AuthorSurname1 = dataReader.GetString(3);
+ book.Role1 = dataReader.GetString(4);
+ book.Pseudonim1 = dataReader.GetString(5);
+ book.AuthorFamily2 = dataReader.GetString(6);
+ book.AuthorName2 = dataReader.GetString(7);
+ book.AuthorSurname2 = dataReader.GetString(8);
+ book.Role2 = dataReader.GetString(9);
+ book.Pseudonim2 = dataReader.GetString(10);
+ book.AuthorFamily3 = dataReader.GetString(11);
+ book.AuthorName3 = dataReader.GetString(12);
+ book.AuthorSurname3 = dataReader.GetString(13);
+ book.Role3 = dataReader.GetString(14);
+ book.Pseudonim3 = dataReader.GetString(15);
+ book.AuthorFamily4 = dataReader.GetString(16);
+ book.AuthorName4 = dataReader.GetString(17);
+ book.AuthorSurname4 = dataReader.GetString(18);
+ book.Role4 = dataReader.GetString(19);
+ book.Pseudonim4 = dataReader.GetString(20);
+ book.Series1 = dataReader.GetString(21);
+ book.Series2 = dataReader.GetString(22);
+ book.Series3 = dataReader.GetString(23);
+ book.Series4 = dataReader.GetString(24);
+ book.Title = dataReader.GetString(25);
+ book.Format = dataReader.GetString(26);
+ book.Version = dataReader.GetString(27);
+ book.SizeInBytes = dataReader.GetInt64(28);
+ book.Md5Hash = dataReader.GetString(29);
+ book.Path = dataReader.GetString(30);
+ book.Language = dataReader.GetString(31);
+ book.Pages = dataReader.GetString(32);
+ book.Identifier = dataReader.GetString(33);
+ book.Year = dataReader.GetString(34);
+ book.Publisher = dataReader.GetString(35);
+ book.Edition = dataReader.GetString(36);
+ book.Commentary = dataReader.GetString(37);
+ book.AddedDateTime = ParseNullableDbDate(dataReader.GetValue(38));
+ book.LastModifiedDateTime = ParseDbDate(dataReader.GetString(39));
+ book.RussianAuthorFamily = dataReader.GetString(40);
+ book.RussianAuthorName = dataReader.GetString(41);
+ book.RussianAuthorSurname = dataReader.GetString(42);
+ book.Cover = dataReader.GetString(43);
+ book.GoogleBookId = dataReader.GetString(44);
+ book.Asin = dataReader.GetString(45);
+ book.AuthorHash = dataReader.GetString(46);
+ book.TitleHash = dataReader.GetString(47);
+ book.Visible = dataReader.GetString(48);
+ book.LibgenId = dataReader.GetInt32(49);
+ return book;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private SciMagArticle ReadSciMagArticle(SQLiteDataReader dataReader)
+ {
+ SciMagArticle article = new SciMagArticle();
+ article.Id = dataReader.GetInt32(0);
+ article.Doi = dataReader.GetString(1);
+ article.Doi2 = dataReader.GetString(2);
+ article.Title = dataReader.GetString(3);
+ article.Authors = dataReader.GetString(4);
+ article.Year = dataReader.GetString(5);
+ article.Month = dataReader.GetString(6);
+ article.Day = dataReader.GetString(7);
+ article.Volume = dataReader.GetString(8);
+ article.Issue = dataReader.GetString(9);
+ article.FirstPage = dataReader.GetString(10);
+ article.LastPage = dataReader.GetString(11);
+ article.Journal = dataReader.GetString(12);
+ article.Isbn = dataReader.GetString(13);
+ article.Issnp = dataReader.GetString(14);
+ article.Issne = dataReader.GetString(15);
+ article.Md5Hash = dataReader.GetString(16);
+ article.SizeInBytes = dataReader.GetInt64(17);
+ article.AddedDateTime = ParseNullableDbDate(dataReader.GetValue(18));
+ article.JournalId = dataReader.GetString(19);
+ article.AbstractUrl = dataReader.GetString(20);
+ article.Attribute1 = dataReader.GetString(21);
+ article.Attribute2 = dataReader.GetString(22);
+ article.Attribute3 = dataReader.GetString(23);
+ article.Attribute4 = dataReader.GetString(24);
+ article.Attribute5 = dataReader.GetString(25);
+ article.Attribute6 = dataReader.GetString(26);
+ article.Visible = dataReader.GetString(27);
+ article.PubmedId = dataReader.GetString(28);
+ article.Pmc = dataReader.GetString(29);
+ article.Pii = dataReader.GetString(30);
+ article.LibgenId = dataReader.GetInt32(31);
+ return article;
+ }
+
+ private string EscapeSearchQuery(string originalSearchQuery)
+ {
+ List searchQueryBuilder = new List();
+ foreach (string searchQueryPart in originalSearchQuery.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))
+ {
+ switch (searchQueryPart)
+ {
+ case "AND":
+ case "OR":
+ case "NOT":
+ searchQueryBuilder.Add(searchQueryPart);
+ continue;
+ default:
+ if (searchQueryPart.Length > 1 && searchQueryPart.EndsWith("*"))
+ {
+ searchQueryBuilder.Add($"\"{searchQueryPart.Substring(0, searchQueryPart.Length - 1)}\"*");
+ }
+ else
+ {
+ searchQueryBuilder.Add($"\"{searchQueryPart}\"");
+ }
+ break;
+ }
+ }
+ return String.Join(" ", searchQueryBuilder);
+ }
+
+ private string GetSearchCommandWithLimit(string searchCommand, int? resultLimit)
+ {
+ return searchCommand + (resultLimit.HasValue ? " LIMIT " + resultLimit.Value : String.Empty);
}
private void ExecuteCommands(params string[] commands)
@@ -322,5 +814,35 @@ private void ExecuteCommands(params string[] commands)
}
}
}
+
+ private int ExecuteScalarCommand(string commandText)
+ {
+ using (SQLiteCommand command = connection.CreateCommand())
+ {
+ command.CommandText = commandText;
+ object objectResult = command.ExecuteScalar();
+ return objectResult != DBNull.Value ? (int)(long)objectResult : 0;
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private DateTime ParseDbDate(string input)
+ {
+ return DateTime.ParseExact(input, "s", CultureInfo.InvariantCulture);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private DateTime? ParseNullableDbDate(object input)
+ {
+ if (input is string inputString)
+ {
+ if (String.IsNullOrEmpty(inputString))
+ {
+ return null;
+ }
+ return ParseDbDate(inputString);
+ }
+ return null;
+ }
}
}
diff --git a/Models/Database/SqlScripts.cs b/Models/Database/SqlScripts.cs
index 0427bff..0c7dc0b 100644
--- a/Models/Database/SqlScripts.cs
+++ b/Models/Database/SqlScripts.cs
@@ -1,15 +1,23 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibgenDesktop.Models.Database
+namespace LibgenDesktop.Models.Database
{
internal static class SqlScripts
{
- public const string CREATE_BOOKS_TABLE =
- "CREATE TABLE IF NOT EXISTS books (" +
+ public const string CHECK_IF_METADATA_TABLE_EXIST = @"SELECT COUNT(name) FROM sqlite_master WHERE type=""table"" AND name=""metadata""";
+
+ public const string CREATE_METADATA_TABLE =
+ "CREATE TABLE IF NOT EXISTS metadata (" +
+ "Key TEXT PRIMARY KEY NOT NULL," +
+ "Value TEXT" +
+ ")";
+
+ public const string GET_ALL_METADATA_ITEMS = "SELECT Key,Value FROM metadata";
+
+ public const string INSERT_METADATA_ITEM = "INSERT INTO metadata VALUES (@Key,@Value)";
+
+ public const string UPDATE_METADATA_ITEM = "UPDATE metadata SET Value = @Value WHERE Key = @Key";
+
+ public const string CREATE_NON_FICTION_TABLE =
+ "CREATE TABLE IF NOT EXISTS non_fiction (" +
"Id INTEGER PRIMARY KEY NOT NULL," +
"Title TEXT," +
"VolumeInfo TEXT," +
@@ -34,7 +42,7 @@ internal static class SqlScripts
"Ddc TEXT," +
"Lcc TEXT," +
"Doi TEXT," +
- "GoogleBookid TEXT," +
+ "GoogleBookId TEXT," +
"OpenLibraryId TEXT," +
"Commentary TEXT," +
"Dpi INTEGER," +
@@ -60,31 +68,156 @@ internal static class SqlScripts
"LibgenId INTEGER NOT NULL" +
")";
- public const string CREATE_BOOKS_FTS_TABLE =
- "CREATE VIRTUAL TABLE IF NOT EXISTS books_fts USING fts5 (Title, Series, Authors, Publisher, IdentifierPlain, " +
- "content=books, content_rowid=Id)";
+ public const string CREATE_NON_FICTION_FTS_TABLE =
+ "CREATE VIRTUAL TABLE IF NOT EXISTS non_fiction_fts USING fts5 (Title, Series, Authors, Publisher, IdentifierPlain, " +
+ "content=non_fiction, content_rowid=Id)";
- public const string COUNT_BOOKS = "SELECT MAX(Id) FROM books LIMIT 1";
+ public const string COUNT_NON_FICTION = "SELECT MAX(Id) FROM non_fiction LIMIT 1";
- public const string GET_ALL_BOOKS = "SELECT Id,Title,Authors,Series,Year,Publisher,Format,SizeInBytes,Searchable FROM books ORDER BY Id";
+ public const string GET_NON_FICTION_BY_ID = "SELECT * FROM non_fiction WHERE Id = @Id";
- public const string GET_BOOK_BY_ID = "SELECT Id,Title,VolumeInfo,Series,Periodical,Authors,Year,Edition,Publisher,City," +
- "Pages,PagesInFile,Language,Topic,Library,Issue,Identifier,Issn,Asin,Udc,Lbc,Ddc,Lcc,Doi," +
- "GoogleBookid,OpenLibraryId,Commentary,Dpi,Color,Cleaned,Orientation,Paginated,Scanned,Bookmarked," +
- "Searchable,SizeInBytes,Format,Md5Hash,Generic,Visible,Locator,Local,AddedDateTime," +
- "LastModifiedDateTime,CoverUrl,Tags,IdentifierPlain,LibgenId FROM books WHERE Id = @Id";
+ public const string SEARCH_NON_FICTION = "SELECT * FROM non_fiction " +
+ "WHERE Id IN (SELECT rowid FROM non_fiction_fts WHERE non_fiction_fts MATCH @SearchQuery) ORDER BY Id";
- public const string SEARCH_BOOKS = "SELECT Id,Title,Authors,Series,Year,Publisher,Format,SizeInBytes,Searchable FROM books " +
- "WHERE Id IN (SELECT rowid FROM books_fts WHERE books_fts MATCH @SearchQuery) ORDER BY Id";
-
- public const string INSERT_BOOK =
- "INSERT INTO books VALUES (@Id,@Title,@VolumeInfo,@Series,@Periodical,@Authors,@Year,@Edition,@Publisher,@City," +
+ public const string INSERT_NON_FICTION =
+ "INSERT INTO non_fiction VALUES (@Id,@Title,@VolumeInfo,@Series,@Periodical,@Authors,@Year,@Edition,@Publisher,@City," +
"@Pages,@PagesInFile,@Language,@Topic,@Library,@Issue,@Identifier,@Issn,@Asin,@Udc,@Lbc,@Ddc,@Lcc,@Doi," +
- "@GoogleBookid,@OpenLibraryId,@Commentary,@Dpi,@Color,@Cleaned,@Orientation,@Paginated,@Scanned,@Bookmarked," +
+ "@GoogleBookId,@OpenLibraryId,@Commentary,@Dpi,@Color,@Cleaned,@Orientation,@Paginated,@Scanned,@Bookmarked," +
"@Searchable,@SizeInBytes,@Format,@Md5Hash,@Generic,@Visible,@Locator,@Local,@AddedDateTime," +
"@LastModifiedDateTime,@CoverUrl,@Tags,@IdentifierPlain,@LibgenId)";
- public const string INSERT_BOOK_FTS =
- "INSERT INTO books_fts VALUES (@Title,@Series,@Authors,@Publisher,@IdentifierPlain)";
+ public const string INSERT_NON_FICTION_FTS =
+ "INSERT INTO non_fiction_fts VALUES (@Title,@Series,@Authors,@Publisher,@IdentifierPlain)";
+
+ public const string CREATE_FICTION_TABLE =
+ "CREATE TABLE IF NOT EXISTS fiction (" +
+ "Id INTEGER PRIMARY KEY NOT NULL," +
+ "AuthorFamily1 TEXT," +
+ "AuthorName1 TEXT," +
+ "AuthorSurname1 TEXT," +
+ "Role1 TEXT," +
+ "Pseudonim1 TEXT," +
+ "AuthorFamily2 TEXT," +
+ "AuthorName2 TEXT," +
+ "AuthorSurname2 TEXT," +
+ "Role2 TEXT," +
+ "Pseudonim2 TEXT," +
+ "AuthorFamily3 TEXT," +
+ "AuthorName3 TEXT," +
+ "AuthorSurname3 TEXT," +
+ "Role3 TEXT," +
+ "Pseudonim3 TEXT," +
+ "AuthorFamily4 TEXT," +
+ "AuthorName4 TEXT," +
+ "AuthorSurname4 TEXT," +
+ "Role4 TEXT," +
+ "Pseudonim4 TEXT," +
+ "Series1 TEXT," +
+ "Series2 TEXT," +
+ "Series3 TEXT," +
+ "Series4 TEXT," +
+ "Title TEXT," +
+ "Format TEXT," +
+ "Version TEXT," +
+ "SizeInBytes INTEGER NOT NULL," +
+ "Md5Hash TEXT," +
+ "Path TEXT," +
+ "Language TEXT," +
+ "Pages TEXT," +
+ "Identifier TEXT," +
+ "Year TEXT," +
+ "Publisher TEXT," +
+ "Edition TEXT," +
+ "Commentary TEXT," +
+ "AddedDateTime TEXT," +
+ "LastModifiedDateTime TEXT NOT NULL," +
+ "RussianAuthorFamily TEXT," +
+ "RussianAuthorName TEXT," +
+ "RussianAuthorSurname TEXT," +
+ "Cover TEXT," +
+ "GoogleBookId TEXT," +
+ "Asin TEXT," +
+ "AuthorHash TEXT," +
+ "TitleHash TEXT," +
+ "Visible TEXT," +
+ "LibgenId INTEGER NOT NULL" +
+ ")";
+
+ public const string CREATE_FICTION_FTS_TABLE =
+ "CREATE VIRTUAL TABLE IF NOT EXISTS fiction_fts USING fts5 (Title, AuthorFamily1, AuthorName1, AuthorSurname1, Pseudonim1, " +
+ "AuthorFamily2, AuthorName2, AuthorSurname2, Pseudonim2, AuthorFamily3, AuthorName3, AuthorSurname3, Pseudonim3, " +
+ "AuthorFamily4, AuthorName4, AuthorSurname4, Pseudonim4, RussianAuthorFamily, RussianAuthorName, RussianAuthorSurname, " +
+ "Series1, Series2, Series3, Series4, Publisher, Identifier, content=fiction, content_rowid=Id)";
+
+ public const string COUNT_FICTION = "SELECT MAX(Id) FROM fiction LIMIT 1";
+
+ public const string GET_FICTION_BY_ID = "SELECT * FROM fiction WHERE Id = @Id";
+
+ public const string SEARCH_FICTION = "SELECT * FROM fiction WHERE Id IN (SELECT rowid FROM fiction_fts WHERE fiction_fts MATCH @SearchQuery) ORDER BY Id";
+
+ public const string INSERT_FICTION =
+ "INSERT INTO fiction VALUES (@Id,@AuthorFamily1,@AuthorName1,@AuthorSurname1,@Role1,@Pseudonim1,@AuthorFamily2,@AuthorName2,@AuthorSurname2,@Role2,@Pseudonim2," +
+ "@AuthorFamily3,@AuthorName3,@AuthorSurname3,@Role3,@Pseudonim3,@AuthorFamily4,@AuthorName4,@AuthorSurname4,@Role4,@Pseudonim4,@Series1,@Series2,@Series3,@Series4," +
+ "@Title,@Format,@Version,@SizeInBytes,@Md5Hash,@Path,@Language,@Pages,@Identifier,@Year,@Publisher,@Edition,@Commentary,@AddedDateTime,@LastModifiedDateTime," +
+ "@RussianAuthorFamily,@RussianAuthorName,@RussianAuthorSurname,@Cover,@GoogleBookId,@Asin,@AuthorHash,@TitleHash,@Visible,@LibgenId)";
+
+ public const string INSERT_FICTION_FTS =
+ "INSERT INTO fiction_fts VALUES (@Title,@AuthorFamily1,@AuthorName1,@AuthorSurname1,@Pseudonim1," +
+ "@AuthorFamily2, @AuthorName2, @AuthorSurname2, @Pseudonim2, @AuthorFamily3, @AuthorName3, @AuthorSurname3, @Pseudonim3, " +
+ "@AuthorFamily4, @AuthorName4, @AuthorSurname4, @Pseudonim4, @RussianAuthorFamily, @RussianAuthorName, @RussianAuthorSurname, " +
+ "@Series1, @Series2, @Series3, @Series4, @Publisher, @Identifier)";
+
+ public const string CREATE_SCIMAG_TABLE =
+ "CREATE TABLE IF NOT EXISTS scimag (" +
+ "Id INTEGER PRIMARY KEY NOT NULL," +
+ "Doi TEXT," +
+ "Doi2 TEXT," +
+ "Title TEXT," +
+ "Authors TEXT," +
+ "Year TEXT," +
+ "Month TEXT," +
+ "Day TEXT," +
+ "Volume TEXT," +
+ "Issue TEXT," +
+ "FirstPage TEXT," +
+ "LastPage TEXT," +
+ "Journal TEXT," +
+ "Isbn TEXT," +
+ "Issnp TEXT," +
+ "Issne TEXT," +
+ "Md5Hash TEXT," +
+ "SizeInBytes INTEGER NOT NULL," +
+ "AddedDateTime TEXT," +
+ "JournalId TEXT," +
+ "AbstractUrl TEXT," +
+ "Attribute1 TEXT," +
+ "Attribute2 TEXT," +
+ "Attribute3 TEXT," +
+ "Attribute4 TEXT," +
+ "Attribute5 TEXT," +
+ "Attribute6 TEXT," +
+ "Visible TEXT," +
+ "PubmedId TEXT," +
+ "Pmc TEXT," +
+ "Pii TEXT," +
+ "LibgenId INTEGER NOT NULL" +
+ ")";
+
+ public const string CREATE_SCIMAG_FTS_TABLE =
+ "CREATE VIRTUAL TABLE IF NOT EXISTS scimag_fts USING fts5 (Title, Authors, Doi, Doi2, PubmedId, Journal, Issnp, Issne, content=scimag, content_rowid=Id)";
+
+ public const string COUNT_SCIMAG = "SELECT MAX(Id) FROM scimag LIMIT 1";
+
+ public const string GET_SCIMAG_BY_ID = "SELECT * FROM scimag WHERE Id = @Id";
+
+ public const string SEARCH_SCIMAG = "SELECT * FROM scimag WHERE Id IN (SELECT rowid FROM scimag_fts WHERE scimag_fts MATCH @SearchQuery) ORDER BY Id";
+
+ public const string INSERT_SCIMAG =
+ "INSERT INTO scimag VALUES (@Id,@Doi,@Doi2,@Title,@Authors,@Year,@Month,@Day,@Volume,@Issue,@FirstPage,@LastPage,@Journal,@Isbn,@Issnp,@Issne," +
+ "@Md5Hash,@SizeInBytes,@AddedDateTime,@JournalId,@AbstractUrl,@Attribute1,@Attribute2,@Attribute3,@Attribute4,@Attribute5,@Attribute6," +
+ "@Visible,@PubmedId,@Pmc,@Pii,@LibgenId)";
+
+ public const string INSERT_SCIMAG_FTS =
+ "INSERT INTO scimag_fts VALUES (@Title,@Authors,@Doi,@Doi2,@PubmedId,@Journal,@Issnp,@Issne)";
}
}
diff --git a/Models/Entities/Book.cs b/Models/Entities/Book.cs
deleted file mode 100644
index ab797fb..0000000
--- a/Models/Entities/Book.cs
+++ /dev/null
@@ -1,110 +0,0 @@
-using System;
-using System.Text;
-using LibgenDesktop.Models.Utils;
-
-namespace LibgenDesktop.Models.Entities
-{
- internal class Book
- {
- internal class BookExtendedProperties
- {
- public string VolumeInfo { get; set; }
- public string Periodical { get; set; }
- public string Edition { get; set; }
- public string City { get; set; }
- public string Pages { get; set; }
- public int PagesInFile { get; set; }
- public string Language { get; set; }
- public string Topic { get; set; }
- public string Library { get; set; }
- public string Issue { get; set; }
- public string Identifier { get; set; }
- public string Issn { get; set; }
- public string Asin { get; set; }
- public string Udc { get; set; }
- public string Lbc { get; set; }
- public string Ddc { get; set; }
- public string Lcc { get; set; }
- public string Doi { get; set; }
- public string GoogleBookid { get; set; }
- public string OpenLibraryId { get; set; }
- public string Commentary { get; set; }
- public int Dpi { get; set; }
- public string Color { get; set; }
- public string Cleaned { get; set; }
- public string Orientation { get; set; }
- public string Paginated { get; set; }
- public string Scanned { get; set; }
- public string Bookmarked { get; set; }
- public string Md5Hash { get; set; }
- public string Generic { get; set; }
- public string Visible { get; set; }
- public string Locator { get; set; }
- public int Local { get; set; }
- public DateTime AddedDateTime { get; set; }
- public DateTime LastModifiedDateTime { get; set; }
- public string CoverUrl { get; set; }
- public string Tags { get; set; }
- public string IdentifierPlain { get; set; }
- public int LibgenId { get; set; }
-
- public string AddedDateTimeString => AddedDateTime.ToString("dd.MM.yyyy HH:mm:ss");
- public string LastModifiedDateTimeString => LastModifiedDateTime.ToString("dd.MM.yyyy HH:mm:ss");
- public string BookmarkedString => StringBooleanToLabelString(Bookmarked, "есть", "нет", "неизвестно");
- public string ScannedString => StringBooleanToLabelString(Scanned, "да", "нет", "неизвестно");
- public string OrientationString => StringBooleanToLabelString(Orientation, "портретная", "альбомная", "неизвестно");
- public string PaginatedString => StringBooleanToLabelString(Paginated, "да", "нет", "неизвестно");
- public string ColorString => StringBooleanToLabelString(Color, "да", "нет", "неизвестно");
- public string CleanedString => StringBooleanToLabelString(Cleaned, "да", "нет", "неизвестно");
-
- public string PagesString
- {
- get
- {
- StringBuilder resultBuilder = new StringBuilder();
- if (!String.IsNullOrWhiteSpace(Pages))
- {
- resultBuilder.Append(Pages);
- }
- else
- {
- resultBuilder.Append("неизвестно");
- }
- resultBuilder.Append(" (содержательная часть) / ");
- resultBuilder.Append(PagesInFile.ToString());
- resultBuilder.Append(" (всего в файле)");
- return resultBuilder.ToString();
- }
- }
- }
-
- public int Id { get; set; }
- public string Title { get; set; }
- public string Series { get; set; }
- public string Authors { get; set; }
- public string Year { get; set; }
- public string Publisher { get; set; }
- public long SizeInBytes { get; set; }
- public string Format { get; set; }
- public string Searchable { get; set; }
- public BookExtendedProperties ExtendedProperties { get; set; }
-
- public string FileSizeString => Formatters.FileSizeToString(SizeInBytes, false);
- public string FileSizeWithBytesString => Formatters.FileSizeToString(SizeInBytes, true);
- public bool Ocr => Searchable == "1";
- public string SearchableString => StringBooleanToLabelString(Searchable, "да", "нет", "неизвестно");
-
- private static string StringBooleanToLabelString(string value, string value1Label, string value0Label, string valueUnknownLabel)
- {
- switch (value)
- {
- case "0":
- return value0Label;
- case "1":
- return value1Label;
- default:
- return valueUnknownLabel;
- }
- }
- }
-}
diff --git a/Models/Entities/DatabaseMetadata.cs b/Models/Entities/DatabaseMetadata.cs
new file mode 100644
index 0000000..58b66ec
--- /dev/null
+++ b/Models/Entities/DatabaseMetadata.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+
+namespace LibgenDesktop.Models.Entities
+{
+ internal class DatabaseMetadata
+ {
+ internal class FieldDefinition
+ {
+ public FieldDefinition(string fieldName, Func getter, Action setter)
+ {
+ FieldName = fieldName;
+ Getter = getter;
+ Setter = setter;
+ }
+
+ public string FieldName { get; }
+ public Func Getter { get; }
+ public Action Setter { get; }
+ }
+
+ static DatabaseMetadata()
+ {
+ FieldDefinitions = new Dictionary();
+ AddField("Version", metadata => metadata.Version, (metadata, value) => metadata.Version = value);
+ }
+
+ public static Dictionary FieldDefinitions { get; }
+
+ public string Version { get; set; }
+
+ private static void AddField(string fieldName, Func getter, Action setter)
+ {
+ FieldDefinitions.Add(fieldName.ToLower(), new FieldDefinition(fieldName, getter, setter));
+ }
+ }
+}
diff --git a/Models/Entities/FictionBook.cs b/Models/Entities/FictionBook.cs
new file mode 100644
index 0000000..bb7c3ff
--- /dev/null
+++ b/Models/Entities/FictionBook.cs
@@ -0,0 +1,198 @@
+using System;
+using System.Runtime.CompilerServices;
+using System.Text;
+using LibgenDesktop.Models.Utils;
+
+namespace LibgenDesktop.Models.Entities
+{
+ internal class FictionBook
+ {
+ private string authors;
+ private string series;
+ private string russianAuthor;
+
+ public FictionBook()
+ {
+ authors = null;
+ series = null;
+ russianAuthor = null;
+ }
+
+ public int Id { get; set; }
+ public string AuthorFamily1 { get; set; }
+ public string AuthorName1 { get; set; }
+ public string AuthorSurname1 { get; set; }
+ public string Role1 { get; set; }
+ public string Pseudonim1 { get; set; }
+ public string AuthorFamily2 { get; set; }
+ public string AuthorName2 { get; set; }
+ public string AuthorSurname2 { get; set; }
+ public string Role2 { get; set; }
+ public string Pseudonim2 { get; set; }
+ public string AuthorFamily3 { get; set; }
+ public string AuthorName3 { get; set; }
+ public string AuthorSurname3 { get; set; }
+ public string Role3 { get; set; }
+ public string Pseudonim3 { get; set; }
+ public string AuthorFamily4 { get; set; }
+ public string AuthorName4 { get; set; }
+ public string AuthorSurname4 { get; set; }
+ public string Role4 { get; set; }
+ public string Pseudonim4 { get; set; }
+ public string Series1 { get; set; }
+ public string Series2 { get; set; }
+ public string Series3 { get; set; }
+ public string Series4 { get; set; }
+ public string Title { get; set; }
+ public string Format { get; set; }
+ public string Version { get; set; }
+ public long SizeInBytes { get; set; }
+ public string Md5Hash { get; set; }
+ public string Path { get; set; }
+ public string Language { get; set; }
+ public string Pages { get; set; }
+ public string Identifier { get; set; }
+ public string Year { get; set; }
+ public string Publisher { get; set; }
+ public string Edition { get; set; }
+ public string Commentary { get; set; }
+ public DateTime? AddedDateTime { get; set; }
+ public DateTime LastModifiedDateTime { get; set; }
+ public string RussianAuthorFamily { get; set; }
+ public string RussianAuthorName { get; set; }
+ public string RussianAuthorSurname { get; set; }
+ public string Cover { get; set; }
+ public string GoogleBookId { get; set; }
+ public string Asin { get; set; }
+ public string AuthorHash { get; set; }
+ public string TitleHash { get; set; }
+ public string Visible { get; set; }
+ public int LibgenId { get; set; }
+
+ public string YearString => Year != "0" ? Year : String.Empty;
+ public string PagesString => Pages != "0" ? Pages : "неизвестно";
+ public string FileSizeString => Formatters.FileSizeToString(SizeInBytes, false);
+ public string FileSizeWithBytesString => Formatters.FileSizeToString(SizeInBytes, true);
+ public string AddedDateTimeString => AddedDateTime != null ? AddedDateTime.Value.ToString("dd.MM.yyyy HH:mm:ss") : "неизвестно";
+ public string LastModifiedDateTimeString => LastModifiedDateTime.ToString("dd.MM.yyyy HH:mm:ss");
+
+ public string Authors
+ {
+ get
+ {
+ if (authors == null)
+ {
+ StringBuilder authorsStringBuilder = new StringBuilder();
+ AppendAuthorString(authorsStringBuilder, AuthorName1, AuthorSurname1, AuthorFamily1, Pseudonim1, Role1);
+ AppendAuthorString(authorsStringBuilder, AuthorName2, AuthorSurname2, AuthorFamily2, Pseudonim2, Role2);
+ AppendAuthorString(authorsStringBuilder, AuthorName3, AuthorSurname3, AuthorFamily3, Pseudonim3, Role3);
+ AppendAuthorString(authorsStringBuilder, AuthorName4, AuthorSurname4, AuthorFamily4, Pseudonim4, Role4);
+ authors = authorsStringBuilder.ToString();
+ }
+ return authors;
+ }
+ }
+
+ public string Series
+ {
+ get
+ {
+ if (series == null)
+ {
+ StringBuilder seriesStringBuilder = new StringBuilder();
+ foreach (string seriesItem in new[] { Series1, Series2, Series3, Series4 })
+ {
+ if (!String.IsNullOrWhiteSpace(seriesItem))
+ {
+ if (seriesStringBuilder.Length > 0)
+ {
+ seriesStringBuilder.Append("; ");
+ }
+ seriesStringBuilder.Append(seriesItem);
+ }
+ }
+ series = seriesStringBuilder.ToString();
+ }
+ return series;
+ }
+ }
+
+ public string RussianAuthor
+ {
+ get
+ {
+ if (russianAuthor == null)
+ {
+ StringBuilder russianAuthorStringBuilder = new StringBuilder();
+ AppendAuthorString(russianAuthorStringBuilder, RussianAuthorName, RussianAuthorSurname, RussianAuthorFamily, null, null);
+ russianAuthor = russianAuthorStringBuilder.ToString();
+ }
+ return russianAuthor;
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void AppendAuthorString(StringBuilder stringBuilder, string name, string surname, string familyName, string pseudonim, string role)
+ {
+ bool hasName = !String.IsNullOrWhiteSpace(name);
+ bool hasSurname = !String.IsNullOrWhiteSpace(surname);
+ bool hasFamilyName = !String.IsNullOrWhiteSpace(familyName);
+ bool hasPseudonim = !String.IsNullOrWhiteSpace(pseudonim);
+ bool hasRole = !String.IsNullOrWhiteSpace(role);
+ if (hasName || hasSurname || hasFamilyName || hasPseudonim || hasRole)
+ {
+ if (stringBuilder.Length > 0)
+ {
+ stringBuilder.Append("; ");
+ }
+ bool firstPart = true;
+ if (hasName)
+ {
+ stringBuilder.Append(name);
+ firstPart = false;
+ }
+ if (hasSurname)
+ {
+ if (!firstPart)
+ {
+ stringBuilder.Append(" ");
+ }
+ stringBuilder.Append(surname);
+ firstPart = false;
+ }
+ if (hasFamilyName)
+ {
+ if (!firstPart)
+ {
+ stringBuilder.Append(" ");
+ }
+ stringBuilder.Append(familyName);
+ firstPart = false;
+ }
+ if (hasPseudonim)
+ {
+ if (!firstPart)
+ {
+ stringBuilder.Append(" (");
+ }
+ stringBuilder.Append(pseudonim);
+ if (!firstPart)
+ {
+ stringBuilder.Append(")");
+ }
+ firstPart = false;
+ }
+ if (hasRole)
+ {
+ if (!firstPart)
+ {
+ stringBuilder.Append(" ");
+ }
+ stringBuilder.Append("(");
+ stringBuilder.Append(role);
+ stringBuilder.Append(")");
+ }
+ }
+ }
+ }
+}
diff --git a/Models/Entities/NonFictionBook.cs b/Models/Entities/NonFictionBook.cs
new file mode 100644
index 0000000..40181ed
--- /dev/null
+++ b/Models/Entities/NonFictionBook.cs
@@ -0,0 +1,104 @@
+using System;
+using System.Text;
+using LibgenDesktop.Models.Utils;
+
+namespace LibgenDesktop.Models.Entities
+{
+ internal class NonFictionBook
+ {
+ public int Id { get; set; }
+ public string Title { get; set; }
+ public string VolumeInfo { get; set; }
+ public string Series { get; set; }
+ public string Periodical { get; set; }
+ public string Authors { get; set; }
+ public string Year { get; set; }
+ public string Edition { get; set; }
+ public string Publisher { get; set; }
+ public string City { get; set; }
+ public string Pages { get; set; }
+ public int PagesInFile { get; set; }
+ public string Language { get; set; }
+ public string Topic { get; set; }
+ public string Library { get; set; }
+ public string Issue { get; set; }
+ public string Identifier { get; set; }
+ public string Issn { get; set; }
+ public string Asin { get; set; }
+ public string Udc { get; set; }
+ public string Lbc { get; set; }
+ public string Ddc { get; set; }
+ public string Lcc { get; set; }
+ public string Doi { get; set; }
+ public string GoogleBookId { get; set; }
+ public string OpenLibraryId { get; set; }
+ public string Commentary { get; set; }
+ public int Dpi { get; set; }
+ public string Color { get; set; }
+ public string Cleaned { get; set; }
+ public string Orientation { get; set; }
+ public string Paginated { get; set; }
+ public string Scanned { get; set; }
+ public string Bookmarked { get; set; }
+ public string Searchable { get; set; }
+ public long SizeInBytes { get; set; }
+ public string Format { get; set; }
+ public string Md5Hash { get; set; }
+ public string Generic { get; set; }
+ public string Visible { get; set; }
+ public string Locator { get; set; }
+ public int Local { get; set; }
+ public DateTime AddedDateTime { get; set; }
+ public DateTime LastModifiedDateTime { get; set; }
+ public string CoverUrl { get; set; }
+ public string Tags { get; set; }
+ public string IdentifierPlain { get; set; }
+ public int LibgenId { get; set; }
+
+ public string FileSizeString => Formatters.FileSizeToString(SizeInBytes, false);
+ public string FileSizeWithBytesString => Formatters.FileSizeToString(SizeInBytes, true);
+ public bool Ocr => Searchable == "1";
+ public string SearchableString => StringBooleanToLabelString(Searchable, "да", "нет", "неизвестно");
+ public string AddedDateTimeString => AddedDateTime.ToString("dd.MM.yyyy HH:mm:ss");
+ public string LastModifiedDateTimeString => LastModifiedDateTime.ToString("dd.MM.yyyy HH:mm:ss");
+ public string BookmarkedString => StringBooleanToLabelString(Bookmarked, "есть", "нет", "неизвестно");
+ public string ScannedString => StringBooleanToLabelString(Scanned, "да", "нет", "неизвестно");
+ public string OrientationString => StringBooleanToLabelString(Orientation, "портретная", "альбомная", "неизвестно");
+ public string PaginatedString => StringBooleanToLabelString(Paginated, "да", "нет", "неизвестно");
+ public string ColorString => StringBooleanToLabelString(Color, "да", "нет", "неизвестно");
+ public string CleanedString => StringBooleanToLabelString(Cleaned, "да", "нет", "неизвестно");
+
+ public string PagesString
+ {
+ get
+ {
+ StringBuilder resultBuilder = new StringBuilder();
+ if (!String.IsNullOrWhiteSpace(Pages))
+ {
+ resultBuilder.Append(Pages);
+ }
+ else
+ {
+ resultBuilder.Append("неизвестно");
+ }
+ resultBuilder.Append(" (содержательная часть) / ");
+ resultBuilder.Append(PagesInFile.ToString());
+ resultBuilder.Append(" (всего в файле)");
+ return resultBuilder.ToString();
+ }
+ }
+
+ private static string StringBooleanToLabelString(string value, string value1Label, string value0Label, string valueUnknownLabel)
+ {
+ switch (value)
+ {
+ case "0":
+ return value0Label;
+ case "1":
+ return value1Label;
+ default:
+ return valueUnknownLabel;
+ }
+ }
+ }
+}
diff --git a/Models/Entities/SciMagArticle.cs b/Models/Entities/SciMagArticle.cs
new file mode 100644
index 0000000..b2060bd
--- /dev/null
+++ b/Models/Entities/SciMagArticle.cs
@@ -0,0 +1,92 @@
+using System;
+using LibgenDesktop.Models.Utils;
+
+namespace LibgenDesktop.Models.Entities
+{
+ internal class SciMagArticle
+ {
+ private string doiString;
+
+ public SciMagArticle()
+ {
+ doiString = null;
+ }
+
+ public int Id { get; set; }
+ public string Doi { get; set; }
+ public string Doi2 { get; set; }
+ public string Title { get; set; }
+ public string Authors { get; set; }
+ public string Year { get; set; }
+ public string Month { get; set; }
+ public string Day { get; set; }
+ public string Volume { get; set; }
+ public string Issue { get; set; }
+ public string FirstPage { get; set; }
+ public string LastPage { get; set; }
+ public string Journal { get; set; }
+ public string Isbn { get; set; }
+ public string Issnp { get; set; }
+ public string Issne { get; set; }
+ public string Md5Hash { get; set; }
+ public long SizeInBytes { get; set; }
+ public DateTime? AddedDateTime { get; set; }
+ public string JournalId { get; set; }
+ public string AbstractUrl { get; set; }
+ public string Attribute1 { get; set; }
+ public string Attribute2 { get; set; }
+ public string Attribute3 { get; set; }
+ public string Attribute4 { get; set; }
+ public string Attribute5 { get; set; }
+ public string Attribute6 { get; set; }
+ public string Visible { get; set; }
+ public string PubmedId { get; set; }
+ public string Pmc { get; set; }
+ public string Pii { get; set; }
+ public int LibgenId { get; set; }
+
+ public string FileSizeString => Formatters.FileSizeToString(SizeInBytes, false);
+ public string FileSizeWithBytesString => Formatters.FileSizeToString(SizeInBytes, true);
+ public string AddedDateTimeString => AddedDateTime != null ? AddedDateTime.Value.ToString("dd.MM.yyyy HH:mm:ss") : "неизвестно";
+
+ public string DoiString
+ {
+ get
+ {
+ if (doiString == null)
+ {
+ if (!String.IsNullOrWhiteSpace(Doi))
+ {
+ doiString = Doi;
+ }
+ if (!String.IsNullOrWhiteSpace(Doi2))
+ {
+ if (doiString.Length > 0)
+ {
+ doiString += "; ";
+ }
+ doiString += Doi2;
+ }
+ }
+ return doiString;
+ }
+ }
+
+ public string PagesString
+ {
+ get
+ {
+ if ((!String.IsNullOrWhiteSpace(FirstPage) && FirstPage != "0") || (!String.IsNullOrWhiteSpace(LastPage) && LastPage != "0"))
+ {
+ string firstPage = FirstPage != "0" ? FirstPage.Trim() + " " : String.Empty;
+ string lastPage = LastPage != "0" ? " " + LastPage.Trim() : String.Empty;
+ return firstPage + "–" + lastPage;
+ }
+ else
+ {
+ return "неизвестно";
+ }
+ }
+ }
+ }
+}
diff --git a/Models/MainModel.cs b/Models/MainModel.cs
index f0eb2f3..e2695c7 100644
--- a/Models/MainModel.cs
+++ b/Models/MainModel.cs
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -8,157 +10,391 @@
using LibgenDesktop.Models.ProgressArgs;
using LibgenDesktop.Models.Settings;
using LibgenDesktop.Models.SqlDump;
-using LibgenDesktop.Models.Utils;
using static LibgenDesktop.Common.Constants;
namespace LibgenDesktop.Models
{
internal class MainModel
{
- private readonly LocalDatabase localDatabase;
+ internal enum DatabaseStatus
+ {
+ OPENED = 1,
+ NOT_FOUND,
+ NOT_SET,
+ CORRUPTED
+ }
+
+ internal enum ImportSqlDumpResult
+ {
+ COMPLETED = 1,
+ CANCELLED,
+ DATA_NOT_FOUND,
+ EXCEPTION
+ }
+
+ private const double IMPORT_PROGRESS_UPDATE_INTERVAL = 0.5;
+ private const double SEARCH_PROGRESS_UPDATE_INTERVAL = 0.1;
+
+ private LocalDatabase localDatabase;
public MainModel()
{
AppSettings = SettingsStorage.LoadSettings();
- localDatabase = new LocalDatabase(AppSettings.DatabaseFileName);
- AllBooks = new AsyncBookCollection();
- SearchResults = new AsyncBookCollection();
+ OpenDatabase(AppSettings.DatabaseFileName);
}
public AppSettings AppSettings { get; }
- public AsyncBookCollection AllBooks { get; }
- public AsyncBookCollection SearchResults { get; }
+ public DatabaseStatus LocalDatabaseStatus { get; private set; }
+ public DatabaseMetadata DatabaseMetadata { get; private set; }
+ public int NonFictionBookCount { get; private set; }
+ public int FictionBookCount { get; private set; }
+ public int SciMagArticleCount { get; private set; }
+
+ public Task> SearchNonFictionAsync(string searchQuery, IProgress progressHandler,
+ CancellationToken cancellationToken)
+ {
+ return SearchItemsAsync(localDatabase.SearchNonFictionBooks, searchQuery, progressHandler, cancellationToken);
+ }
+
+ public Task LoadNonFictionBookAsync(int bookId)
+ {
+ return LoadItemAsync(localDatabase.GetNonFictionBookById, bookId);
+ }
+
+ public Task> SearchFictionAsync(string searchQuery, IProgress progressHandler,
+ CancellationToken cancellationToken)
+ {
+ return SearchItemsAsync(localDatabase.SearchFictionBooks, searchQuery, progressHandler, cancellationToken);
+ }
- public Task LoadAllBooksAsync(IProgress progressHandler, CancellationToken cancellationToken)
+ public Task LoadFictionBookAsync(int bookId)
+ {
+ return LoadItemAsync(localDatabase.GetFictionBookById, bookId);
+ }
+
+ public Task> SearchSciMagAsync(string searchQuery, IProgress progressHandler,
+ CancellationToken cancellationToken)
+ {
+ return SearchItemsAsync(localDatabase.SearchSciMagArticles, searchQuery, progressHandler, cancellationToken);
+ }
+
+ public Task LoadSciMagArticleAsync(int articleId)
+ {
+ return LoadItemAsync(localDatabase.GetSciMagArticleById, articleId);
+ }
+
+ public Task ImportSqlDumpAsync(string sqlDumpFilePath, IProgress