Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,28 @@ public class CollectionIndex : AutoCollectionContext<CollectionIndex, IValue>
private readonly List<IValue> _fields = new List<IValue>();
private readonly IIndexCollectionSource _source;

private readonly IDictionary<CollectionIndexKey, HashSet<IValue>> _data =
private readonly Dictionary<CollectionIndexKey, HashSet<IValue>> _data =
new Dictionary<CollectionIndexKey, HashSet<IValue>>();

public CollectionIndex(IIndexCollectionSource source, IEnumerable<IValue> fields)
{
foreach (var field in fields)
{
if (field is ValueTable.ValueTableColumn column)
column.AddToIndex();
_fields.Add(field);
}

_source = source;
_fields.AddRange(fields);
foreach (var value in _source)
{
ElementAdded(value);
}
}

internal bool CanBeUsedFor(IEnumerable<IValue> searchFields)
{
return _fields.Any() && _fields.ToHashSet().IsSubsetOf(searchFields.ToHashSet());
return _fields.Count > 0 && _fields.All(f => searchFields.Contains(f));
}

private CollectionIndexKey IndexKey(PropertyNameIndexAccessor source)
Expand All @@ -55,11 +65,26 @@ internal void FieldRemoved(IValue field)
{
if (_fields.Contains(field))
{
while (_fields.Contains(field)) _fields.Remove(field);
while (_fields.Contains(field))
{
if (field is ValueTable.ValueTableColumn column)
column.DeleteFromIndex();

_fields.Remove(field);
}
Rebuild();
}
}

internal void ExcludeFields()
{
foreach (var field in _fields)
{
if (field is ValueTable.ValueTableColumn column)
column.DeleteFromIndex();
}
}

internal void ElementAdded(PropertyNameIndexAccessor element)
{
var key = CollectionIndexKey.Extract(element, _fields);
Expand All @@ -82,10 +107,7 @@ internal void ElementRemoved(PropertyNameIndexAccessor element)
}
}

internal void Clear()
{
_data.Clear();
}
internal void Clear() => _data.Clear();

internal void Rebuild()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,26 +32,30 @@ public CollectionIndexes(IIndexCollectionSource owner)
public CollectionIndex Add(string columns)
{
var newIndex = new CollectionIndex(_owner, BuildFieldList(_owner, columns));
newIndex.Rebuild();
_indexes.Add(newIndex);
return newIndex;
}

[ContextMethod("Количество", "Count")]
public override int Count()
{
return _indexes.Count();
return _indexes.Count;
}

[ContextMethod("Удалить", "Delete")]
public void Delete(IValue index)
{
_indexes.Remove(GetIndex(index));
var idx = GetIndex(index);
idx.ExcludeFields();
_indexes.Remove(idx);
}

[ContextMethod("Очистить", "Clear")]
public void Clear()
{
foreach (var idx in _indexes)
idx.ExcludeFields();

_indexes.Clear();
}

Expand Down Expand Up @@ -130,21 +134,18 @@ public CollectionIndex FindSuitableIndex(IEnumerable<IValue> searchFields)
return _indexes.FirstOrDefault(index => index.CanBeUsedFor(searchFields));
}

private static IList<IValue> BuildFieldList(IIndexCollectionSource source, string fieldList)
private static List<IValue> BuildFieldList(IIndexCollectionSource source, string fieldList)
{
var fields = new List<IValue>();
var fieldNames = fieldList.Split(',');
if (string.IsNullOrEmpty(fieldList))
return fields;

var fieldNames = fieldList.Split(',', System.StringSplitOptions.RemoveEmptyEntries);
foreach (var fieldName in fieldNames)
{
if (!string.IsNullOrWhiteSpace(fieldName))
{
var field = source.GetField(fieldName.Trim());
if (field == null)
{
throw ColumnException.WrongColumnName(fieldName);
}
fields.Add(field);
}
{
var name = fieldName.Trim();
var field = source.GetField(name) ?? throw ColumnException.WrongColumnName(fieldName);
fields.Add(field);
}

return fields;
Expand Down
44 changes: 21 additions & 23 deletions src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ public ValueTable()
Columns = new ValueTableColumnCollection(this);
_rows = new List<ValueTableRow>();
Indexes = new CollectionIndexes(this);
}

}
/// <summary>
/// Коллекция колонок
/// </summary>
Expand Down Expand Up @@ -70,7 +70,8 @@ public ValueTableRow Add()
{
var row = new ValueTableRow(this);
_rows.Add(row);
Indexes.ElementAdded(row);
if (Indexes.Count() > 0)
Indexes.ElementAdded(row);
return row;
}

Expand All @@ -83,13 +84,14 @@ public ValueTableRow Add()
[ContextMethod("Вставить", "Insert")]
public ValueTableRow Insert(int index)
{
var row = new ValueTableRow(this);
if (index < 0 || index > _rows.Count)
_rows.Add(row); // для совместимости с 1С, хотя логичней было бы исключение
else
_rows.Insert(index, row);
return Add(); // для совместимости с 1С, хотя логичней было бы исключение

Indexes.ElementAdded(row);
var row = new ValueTableRow(this);
_rows.Insert(index, row);

if (Indexes.Count() > 0)
Indexes.ElementAdded(row);
return row;
}

Expand Down Expand Up @@ -157,7 +159,7 @@ public ArrayImpl UnloadColumn(IValue column)
return result;
}

private List<ValueTableColumn> GetProcessingColumnList(string columnNames, bool emptyListInCaseOfNull = false)
private List<ValueTableColumn> GetProcessingColumnList(string columnNames, bool emptyListInCaseOfNull = false)
{
var processing_list = new List<ValueTableColumn>();
if (string.IsNullOrEmpty(columnNames)) // Передали пустую строку вместо списка колонок
Expand Down Expand Up @@ -312,16 +314,18 @@ public IValue Find(IValue value, string columnNames = null)
}
}
return ValueFactory.Create();
}
}

private ValueTableColumn GetColumnOrThrow(string column_name)
=> this.Columns.FindColumnByName(column_name)
?? throw ColumnException.WrongColumnName(column_name);


private bool CheckFilterCriteria(ValueTableRow Row, StructureImpl Filter)
{
foreach (var kv in Filter)
{
var Column = Columns.FindColumnByName(kv.Key.ToString());
if (Column == null)
throw ColumnException.WrongColumnName(kv.Key.ToString());

var Column = GetColumnOrThrow(kv.Key.ToString());
IValue current = Row.Get(Column);
if (!current.StrictEquals(kv.Value))
return false;
Expand All @@ -344,7 +348,7 @@ public ArrayImpl FindRows(StructureImpl filter)

var mapped = ColumnsMap(filter);
var suitableIndex = Indexes.FindSuitableIndex(mapped.Keys());
var dataToScan = suitableIndex != null ? suitableIndex.GetData(mapped) : _rows;
var dataToScan = suitableIndex?.GetData(mapped) ?? _rows;

foreach (var element in dataToScan)
{
Expand All @@ -361,10 +365,7 @@ private MapImpl ColumnsMap(StructureImpl filter)
var result = new MapImpl();
foreach (var kv in filter)
{
var key = Columns.FindColumnByName(kv.Key.ToString());
if (key == null)
throw ColumnException.WrongColumnName(kv.Key.ToString());

var key = GetColumnOrThrow(kv.Key.ToString());
result.Insert(key, kv.Value);
}

Expand Down Expand Up @@ -653,10 +654,7 @@ private List<ValueTableSortRule> GetSortRules(string Columns)
if (description.Length > 2)
throw RuntimeException.InvalidNthArgumentValue(1);

var sortColumn = this.Columns.FindColumnByName(description[0]);
if (sortColumn == null)
throw ColumnException.WrongColumnName(description[0]);

var sortColumn = GetColumnOrThrow(description[0]);
var rule = new ValueTableSortRule
{
Column = sortColumn,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,21 @@ namespace OneScript.StandardLibrary.Collections.ValueTable
public class ValueTableColumn : AutoContext<ValueTableColumn>
{
private string _title;
private string _name;
private TypeDescription _valueType;
private string _name;
private readonly TypeDescription _valueType;
private readonly WeakReference _owner;
private readonly int _id;

public ValueTableColumn(ValueTableColumnCollection owner, int id, string name, string title, TypeDescription type, int width)

private int _indicesCount = 0;
public bool IsIndexable => _indicesCount != 0;
public void AddToIndex() { _indicesCount++; }
public void DeleteFromIndex() { if (_indicesCount != 0) _indicesCount--; }

public ValueTableColumn(ValueTableColumnCollection owner, string name, string title, TypeDescription type, int width)
{
_name = name;
_title = title;
_valueType = type ?? new TypeDescription();
Width = width;
_id = id;

_owner = new WeakReference(owner);
}
Expand Down Expand Up @@ -65,7 +68,6 @@ public string Name
_title = value;

_name = value;

}
}
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,40 @@ namespace OneScript.StandardLibrary.Collections.ValueTable
[ContextClass("КоллекцияКолонокТаблицыЗначений", "ValueTableColumnCollection")]
public class ValueTableColumnCollection : AutoContext<ValueTableColumnCollection>, ICollectionContext<ValueTableColumn>, IDebugPresentationAcceptor
{
private static readonly StringComparer _namesComparer = StringComparer.OrdinalIgnoreCase;

private readonly List<ValueTableColumn> _columns = new List<ValueTableColumn>();
private readonly StringComparer _namesComparer = StringComparer.OrdinalIgnoreCase;
private readonly ValueTable _owner;
private int maxColumnId = 0;

public ValueTableColumnCollection(ValueTable owner)
{
_owner = owner;
}

public ValueTableColumn AddUnchecked(string name, string title, TypeDescription type = null)
{
var column = new ValueTableColumn(this, name, title, type, 0);
_columns.Add(column);
return column;
}

public ValueTableColumn AddUnchecked(string name, string title = null)
{
var column = new ValueTableColumn(this, name, title ?? name, null, 0);
_columns.Add(column);
return column;
}


private void CheckColumnName(string name)
{
if (!Utils.IsValidIdentifier(name))
throw ColumnException.WrongColumnName(name);

if (FindColumnByName(name) != null)
throw ColumnException.DuplicatedColumnName(name);
}

/// <summary>
/// Добавляет колонку в таблицу значений
/// </summary>
Expand All @@ -46,13 +70,9 @@ public ValueTableColumnCollection(ValueTable owner)
[ContextMethod("Добавить", "Add")]
public ValueTableColumn Add(string name, TypeDescription type = null, string title = null, int width = 0)
{
if (!Utils.IsValidIdentifier(name))
throw ColumnException.WrongColumnName(name);
CheckColumnName(name);

if (FindColumnByName(name) != null)
throw ColumnException.DuplicatedColumnName(name);

var column = new ValueTableColumn(this, ++maxColumnId, name, title, type, width);
var column = new ValueTableColumn(this, name, title, type, width);
_columns.Add(column);

return column;
Expand All @@ -70,13 +90,9 @@ public ValueTableColumn Add(string name, TypeDescription type = null, string tit
[ContextMethod("Вставить", "Insert")]
public ValueTableColumn Insert(int index, string name, TypeDescription type = null, string title = null, int width = 0)
{
if (!Utils.IsValidIdentifier(name))
throw ColumnException.WrongColumnName(name);

if (FindColumnByName(name) != null)
throw ColumnException.DuplicatedColumnName(name);
CheckColumnName(name);

ValueTableColumn column = new ValueTableColumn(this, ++maxColumnId, name, title, type, width);
ValueTableColumn column = new ValueTableColumn(this, name, title, type, width);
_columns.Insert(index, column);

return column;
Expand Down Expand Up @@ -113,10 +129,7 @@ public int Count()
[ContextMethod("Найти", "Find")]
public IValue Find(string name)
{
ValueTableColumn Column = FindColumnByName(name);
if (Column == null)
return ValueFactory.Create();
return Column;
return FindColumnByName(name) ?? ValueFactory.Create();
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,8 @@ public ValueTableRow(ValueTable owner)
_owner = owner;
}

public int Count()
{
return _owner.Columns.Count();
}

public int Count() => _owner.Columns.Count();

public int Count(IBslProcess process) => Count();

/// <summary>
Expand Down Expand Up @@ -89,9 +86,14 @@ public void Set(IValue index, IValue value)

public void Set(ValueTableColumn column, IValue value)
{
_owner.Indexes.ElementRemoved(this);
_data[column] = column.ValueType.AdjustValue(value);
_owner.Indexes.ElementAdded(this);
if (column.IsIndexable)
{
_owner.Indexes.ElementRemoved(this);
_data[column] = column.ValueType.AdjustValue(value);
_owner.Indexes.ElementAdded(this);
}
else
_data[column] = column.ValueType.AdjustValue(value);
}

public void OnOwnerColumnRemoval(ValueTableColumn column)
Expand Down
Loading