Пример #1
0
        /// <summary>
        /// Loads a line of TSV data into this object.
        /// Ignores fields which have no mappings currently.
        /// Length match between header and line has to be guaranteed, because
        /// this method doesn't know enough for a nice error message.
        /// </summary>
        /// <param name="TsvMapping"></param>
        /// <param name="record">Target object</param>
        /// <param name="line">Data from a TSV line per field</param>
        internal void LoadFromTSVLine(TsvMapping <T> TsvMapping, object record, List <string> line)
        {
            for (int propertyIndex = 0; propertyIndex < Properties.Length; propertyIndex++)
            {
                Nullable <int> lineIndex = TsvMapping.FromRecordToTsv[propertyIndex];

                if (lineIndex == null)
                {
                    Properties[propertyIndex].SetValue(record, null);
                }
                else
                {
                    Properties[propertyIndex].SetValue(record, ConvertStringToValue(propertyIndex, line[(int)lineIndex]));
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Decompress the raw data and desirialize the records.
        /// </summary>
        /// <param name="queryPlan">Optional for queries. Filters the recrods if passed.</param>
        internal void DeserializeDecompress(QueryPlan <T> queryPlan = null)
        {
            if (rawCompressedData == null)
            {
                return;
            }

            List <string>  header     = null;
            TsvMapping <T> tsvMapping = null;

            using var ms   = new MemoryStream(rawCompressedData);
            using var gzip = new GZipStream(ms, CompressionMode.Decompress);
            using var tsv  = new TsvReader(gzip);
            int            lineCount      = 0;
            Nullable <int> tsvColumnIndex = null;
            bool           isFirstLine    = true;
            bool           notMatching    = false;

            while (!tsv.EndOfStream)
            {
                var line = tsv.ReadLine();

                if (isFirstLine)
                {
                    // Use its own header for compatibility.
                    header      = line;
                    isFirstLine = false;
                    tsvMapping  = new TsvMapping <T>(table, header);
                    continue;
                }

                if (header.Count != line.Count)
                {
                    throw new Exception($"Header length and column count mismatch in file '{FullPath}' at line {lineCount + 1}.");
                }

                /*
                 *  Filtering by 'Where' expressions
                 */
                if (queryPlan != null)
                {
                    notMatching = false;

                    foreach (var filter in queryPlan.FreeIndexFilters)
                    {
                        tsvColumnIndex = tsvMapping.FromRecordToTsv[filter.Key];

                        if (tsvColumnIndex == null || line[(int)tsvColumnIndex] != filter.Value)
                        {
                            notMatching = true;
                            break;
                        }
                    }

                    if (notMatching)
                    {
                        continue;
                    }
                }

                var record = new T();
                table.LoadFromTSVLine(tsvMapping, record, line);

                /*
                 *  Filtering by flex expressions
                 */
                if (queryPlan != null)
                {
                    notMatching = false;

                    foreach (var exp in queryPlan.Query.FlexFilters)
                    {
                        if (!exp(record))
                        {
                            notMatching = true;
                            break;
                        }
                    }

                    if (notMatching)
                    {
                        continue;
                    }
                }

                string unique = table.GetUnique(record);
                this.data[unique] = record;
                this.lines.Add(record);

                lineCount++;
            }

            /*
             *  Sort records inside the packet
             */
            if (queryPlan != null)
            {
                if (queryPlan.FreeSorting.Count > 0)
                {
                    var props = table.Properties.ToArray();

                    this.lines.Sort((x, y) => {
                        foreach (var directive in queryPlan.FreeSorting)
                        {
                            int dir    = directive.Item2 == SortingDirection.Ascending ? 1 : -1;
                            var valueX = props[directive.Item1].GetValue(x);
                            var valueY = props[directive.Item1].GetValue(y);

                            if (valueX == null && valueY == null)
                            {
                                continue;
                            }

                            if (valueX == null)
                            {
                                return(-dir);
                            }

                            if (valueY == null)
                            {
                                return(dir);
                            }

                            return(((IComparable)valueX).CompareTo((IComparable)valueY) * dir);
                        }

                        return(0);
                    });
                }
            }
        }