public JoinRecordProvider(IRecordProvider leftProvider, IRecordProvider rightProvider, string leftField,
            string rightField)
        {
            this.leftProvider = leftProvider;
            this.rightProvider = rightProvider;
            this.leftField = leftField;
            this.rightField = rightField;

            if (!leftProvider.MetaData.ColumnDescriptors.ContainsKey(leftField))
            {
                throw new MalformedQueryException($"No field named {leftField} found.");
            }
            if (!rightProvider.MetaData.ColumnDescriptors.ContainsKey(rightField))
            {
                throw new MalformedQueryException($"No field named {rightField} found.");
            }
            var leftDescriptor = leftProvider.MetaData.ColumnDescriptors[leftField];
            var rightDescriptor = rightProvider.MetaData.ColumnDescriptors[rightField];
            if (leftDescriptor.Type !=
                rightDescriptor.Type)
            {
                throw new MalformedQueryException($"Field types {leftDescriptor.Type} and {rightDescriptor.Type} dont't match.");
            }

            var allKeys =
                leftProvider.MetaData.ColumnDescriptors.Keys.Union(rightProvider.MetaData.ColumnDescriptors.Keys);
            MetaData = new RecordMetaData();
            foreach (var key in allKeys)
            {
                if (leftProvider.MetaData.ColumnDescriptors.Keys.Contains(key))
                {
                    MetaData.AddField(
                        key,
                        leftProvider.MetaData.ColumnDescriptors[key].Type,
                        leftProvider.MetaData.ColumnDescriptors[key].Width
                        );
                }
                else
                {
                    MetaData.AddField(
                        key,
                        rightProvider.MetaData.ColumnDescriptors[key].Type,
                        rightProvider.MetaData.ColumnDescriptors[key].Width
                        );
                }
            }
        }
 public PracticeDatabaseReader(string filename, IndexManager indexManager,
     IEnumerable<IWhereQueryConstraint> constraints, QueryMode queryMode = QueryMode.Auto)
     : base(filename, indexManager, constraints, queryMode)
 {
     recordMetaData = new RecordMetaData();
     recordMetaData.AddField("date", ColumnType.Int);
     recordMetaData.AddField("id", ColumnType.String, 6);
     recordMetaData.AddField("name", ColumnType.String, 40);
     recordMetaData.AddField("center_name", ColumnType.String, 40);
     recordMetaData.AddField("address", ColumnType.String, 40);
     recordMetaData.AddField("city", ColumnType.String, 40);
     recordMetaData.AddField("region", ColumnType.String, 40);
     recordMetaData.AddField("postal_code", ColumnType.String, 10);
     RecordWidth = recordMetaData.RecordWitdh;
 }
 public SelectionRecordProvider(IEnumerable<string> fields, IRecordProvider provider) : base(provider)
 {
     this.fields = fields;
     MetaData = new RecordMetaData();
     foreach (string field in fields)
     {
         try
         {
             var underlyingColumn = provider.MetaData.ColumnDescriptors[field];
             MetaData.AddField(field, underlyingColumn.Type, underlyingColumn.Width);
         }
         catch (Exception e)
         {
             throw new MalformedQueryException($"No field named {field} found.");                    
         }
         
     }
 }
        protected AggregateRecordProvider(string groupBy, string aggregatedField, IRecordProvider provider)
            : base(provider)
        {
            this.groupBy = groupBy;
            this.aggregatedField = aggregatedField;

            if (!provider.MetaData.ColumnDescriptors.ContainsKey(groupBy))
            {
                throw new MalformedQueryException($"Aggregated table does not contain a field '{groupBy}'");
            }
            if (!provider.MetaData.ColumnDescriptors.ContainsKey(aggregatedField))
            {
                throw new MalformedQueryException($"Aggregated table does not contain a field '{aggregatedField}'");
            }

            MetaData = new RecordMetaData();
            MetaData.AddField(groupBy, ColumnType.String, provider.MetaData.ColumnDescriptors[groupBy].Width);

            if (provider.MetaData.ColumnDescriptors.Count > 2)
            {
                this.provider = new SelectionRecordProvider(new List<string> {groupBy, aggregatedField}, provider);
            }
        }