using Dapper; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using RMuseum.DbContext; using RMuseum.Models.Ganjoor; using RSecurityBackend.Models.Generic; using System; using System.Data; using System.Data.Common; using System.Linq; using System.Threading.Tasks; namespace RMuseum.Services.Implementation { /// /// IGanjoorService implementation /// public class GanjoorService : IGanjoorService { #region SQLite import /// /// imports unimported poem data from a locally accessible ganjoor SqlLite database /// /// public async Task> ImportLocalSQLiteDb() { try { SqliteConnectionStringBuilder connectionStringBuilder = new SqliteConnectionStringBuilder(); connectionStringBuilder.DataSource = Configuration.GetSection("LocalSqliteImport")["FilePath"]; using (SqliteConnection sqliteConnection = new SqliteConnection(connectionStringBuilder.ToString())) { await sqliteConnection.OpenAsync(); IDbConnection dapper = sqliteConnection; using (var sqlConnection = _context.Database.GetDbConnection()) { await sqlConnection.OpenAsync(); foreach (var poet in await dapper.QueryAsync("SELECT * FROM poet ORDER BY id")) { int poetId = (int)poet.id; if ((await _context.GanjoorPoets.Where(p => p.Id == poetId).FirstOrDefaultAsync()) != null) { continue; } DbTransaction transaction = await sqlConnection.BeginTransactionAsync(); try { using (var command = sqlConnection.CreateCommand()) { command.Transaction = transaction; command.CommandText = $"INSERT INTO GanjoorPoets (Id, Name, Description) VALUES (${poet.id}, N'{poet.name}', N'{poet.description}')"; await command.ExecuteNonQueryAsync(); await _ImportSQLiteCatChildren(command, dapper, poetId, 0, "", ""); await transaction.CommitAsync(); } } catch (Exception exp2) { await transaction.RollbackAsync(); return new RServiceResult(false, exp2.ToString()); } } } } } catch(Exception exp) { return new RServiceResult(false, exp.ToString()); } return new RServiceResult(true); } private async Task _ImportSQLiteCatChildren(DbCommand command, IDbConnection dapper, int poetId, int catId, string itemFullTitle, string itemFullSlug) { foreach(var cat in await dapper.QueryAsync($"SELECT * FROM cat WHERE poet_id = {poetId} AND parent_id = {catId} ORDER BY id")) { if (catId == 0) { command.CommandText = $"INSERT INTO GanjoorCategories (Id, PoetId, Title, UrlSlug, FullUrl) VALUES (${cat.id}, {poetId}, N'{cat.text}', '{ _ExtractUrlSlug(cat.url)}', '{itemFullSlug}/{ _ExtractUrlSlug(cat.url)}')"; } else { command.CommandText = $"INSERT INTO GanjoorCategories (Id, PoetId, Title, ParentId, UrlSlug, FullUrl) VALUES (${cat.id}, {poetId}, N'{cat.text}', {catId}, '{ _ExtractUrlSlug(cat.url)}', '{itemFullSlug}/{ _ExtractUrlSlug(cat.url)}')"; } await command.ExecuteNonQueryAsync(); foreach (var poem in await dapper.QueryAsync($"SELECT * FROM poem WHERE cat_id = {cat.id} ORDER BY id")) { command.CommandText = $"INSERT INTO GanjoorPoems (Id, CatId, Title, UrlSlug, FullTitle, FullUrl) VALUES (${poem.id}, {cat.id}, N'{poem.title}', '{ _ExtractUrlSlug(poem.url)}', N'{$"{itemFullTitle}{cat.text} » {poem.title}"}', '{itemFullSlug}/{ _ExtractUrlSlug(cat.url)}/{_ExtractUrlSlug(poem.url)}')"; await command.ExecuteNonQueryAsync(); foreach (var verse in await dapper.QueryAsync($"SELECT * FROM verse WHERE poem_id = {poem.id} ORDER BY vorder")) { command.CommandText = $"INSERT INTO GanjoorVerses (PoemId, VOrder, VersePosition, Text) VALUES (${poem.id}, {verse.vorder}, {verse.position}, N'{verse.text}')"; await command.ExecuteNonQueryAsync(); } } await _ImportSQLiteCatChildren(command, dapper, poetId, (int)cat.id, $"{itemFullTitle}{cat.text} » ", $"{itemFullSlug}/{ _ExtractUrlSlug(cat.url)}"); } } #endregion private static string _ExtractUrlSlug(string slug) { if (!string.IsNullOrEmpty(slug)) { //sample: https://ganjoor.net/hafez if (slug.LastIndexOf('/') != -1) { // => result = hafez slug = slug.Substring(slug.LastIndexOf('/') + 1); } } return slug; } /// /// Database Contetxt /// protected readonly RMuseumDbContext _context; /// /// Configuration /// protected IConfiguration Configuration { get; } /// /// constructor /// /// /// public GanjoorService(RMuseumDbContext context, IConfiguration configuration) { _context = context; Configuration = configuration; } } }