private async Task <byte[]> GenerateCSVStream(IDBCDStorage storage, Parameters parameters, bool newLinesInStrings = true) { if (storage.AvailableColumns.Length == 0) { throw new Exception("No columns found!"); } // NOTE: if newLinesInStrings is obsolete then use StringToCSVCell in ctor Func <string, string> formatter = newLinesInStrings switch { true => StringToCSVCell, _ => StringToCSVCellSingleLine }; var viewFilter = new DBCViewFilter(storage, parameters, formatter); using var exportStream = new MemoryStream(); using var exportWriter = new StreamWriter(exportStream); // write header await exportWriter.WriteLineAsync(string.Join(",", GetColumnNames(storage))); // write records foreach (var item in viewFilter.GetRecords()) { await exportWriter.WriteLineAsync(string.Join(",", item)); } exportWriter.Flush(); return(exportStream.ToArray()); }
public async Task <DataTablesResult> Get(CancellationToken cancellationToken, string name, string build, int draw, int start, int length, bool useHotfixes = false, LocaleFlags locale = LocaleFlags.All_WoW) { var parameters = new Dictionary <string, string>(); if (Request.Method == "POST") { // POST, what site uses foreach (var post in Request.Form) { parameters.Add(post.Key, post.Value); } if (parameters.ContainsKey("draw")) { draw = int.Parse(parameters["draw"]); } if (parameters.ContainsKey("start")) { start = int.Parse(parameters["start"]); } if (parameters.ContainsKey("length")) { length = int.Parse(parameters["length"]); } } else { // GET, backwards compatibility for scripts/users using this foreach (var get in Request.Query) { parameters.Add(get.Key, get.Value); } } if (!parameters.TryGetValue("search[value]", out var searchValue) || string.IsNullOrWhiteSpace(searchValue)) { Logger.WriteLine("Serving data " + start + "," + length + " for dbc " + name + " (" + build + ") for draw " + draw); } else { Logger.WriteLine("Serving data " + start + "," + length + " for dbc " + name + " (" + build + ") for draw " + draw + " with search " + searchValue); } var result = new DataTablesResult { draw = draw }; try { cancellationToken.ThrowIfCancellationRequested(); var storage = await dbcManager.GetOrLoad(name, build, useHotfixes, locale); if (storage == null) { throw new Exception("Definitions for this DB and version combination not found in definition cache!"); } result.recordsTotal = storage.Values.Count(); result.data = new List <string[]>(); if (storage.Values.Count == 0 || storage.AvailableColumns.Length == 0) { return(result); } var viewFilter = new DBCViewFilter(storage, parameters, WebUtility.HtmlEncode); result.data = viewFilter.GetRecords(cancellationToken).ToList(); result.recordsFiltered = result.data.Count; var takeLength = length; if ((start + length) > result.recordsFiltered) { takeLength = result.recordsFiltered - start; } // Temp hackfix: If requested count is higher than the amount of filtered records an error occurs and all rows are returned crashing tabs for large DBs. if (takeLength < 0) { start = 0; takeLength = 0; } result.data = result.data.GetRange(start, takeLength); } catch (Exception e) { Logger.WriteLine("Error occured during serving data: " + e.Message); result.error = e.Message.Replace(SettingManager.dbcDir, ""); } return(result); }