Skip to content

Commit

Permalink
[Database editor] Support for conditions in database table editors
Browse files Browse the repository at this point in the history
  • Loading branch information
BAndysc committed May 8, 2021
1 parent d885c29 commit 004fde7
Show file tree
Hide file tree
Showing 16 changed files with 345 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ public class FieldValueTemplateSelector : IDataTemplate
{
public DataTemplate? GenericTemplate { get; set; }
public DataTemplate? BoolTemplate { get; set; }
public DataTemplate? CommandTemplate { get; set; }

public IControl Build(object param)
{
if (param is ViewModels.MultiRow.DatabaseCellViewModel vm3 && vm3.ActionCommand != null)
return CommandTemplate!.Build(param);
if ((param is DatabaseCellViewModel vm && vm.ParameterValue is ParameterValue<long> holder && holder.Parameter is BoolParameter) ||
(param is ViewModels.MultiRow.DatabaseCellViewModel vm2 && vm2.ParameterValue is ParameterValue<long> holder2 && holder2.Parameter is BoolParameter))
return BoolTemplate!.Build(param);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@
</UserControl.Styles>
<UserControl.DataTemplates>
<helpers:FieldValueTemplateSelector>
<helpers:FieldValueTemplateSelector.CommandTemplate>
<DataTemplate>
<Button Command="{Binding ActionCommand}" CommandParameter="{Binding}" Content="{Binding ActionLabel}" />
</DataTemplate>
</helpers:FieldValueTemplateSelector.CommandTemplate>
<helpers:FieldValueTemplateSelector.BoolTemplate>
<DataTemplate>
<controls2:FastBoolCellView Height="24" Margin="0,0,10,0"
Expand Down
3 changes: 3 additions & 0 deletions WDE.DatabaseEditors.WPF/Helpers/FieldValueTemplateSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ public class FieldValueTemplateSelector : DataTemplateSelector
{
public DataTemplate GenericTemplate { get; set; }
public DataTemplate BoolTemplate { get; set; }
public DataTemplate CommandTemplate { get; set; }

public override DataTemplate SelectTemplate(object param, DependencyObject container)
{
if (param is ViewModels.MultiRow.DatabaseCellViewModel vm3 && vm3.ActionCommand != null)
return CommandTemplate;
if ((param is DatabaseCellViewModel vm && vm.ParameterValue is ParameterValue<long> holder && holder.Parameter is BoolParameter) ||
(param is ViewModels.MultiRow.DatabaseCellViewModel vm2 && vm2.ParameterValue is ParameterValue<long> holder2 && holder2.Parameter is BoolParameter))
return BoolTemplate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplateSelector>
<helpers:FieldValueTemplateSelector>
<helpers:FieldValueTemplateSelector.CommandTemplate>
<DataTemplate>
<Button Command="{Binding ActionCommand}" CommandParameter="{Binding}" Content="{Binding ActionLabel}" />
</DataTemplate>
</helpers:FieldValueTemplateSelector.CommandTemplate>
<helpers:FieldValueTemplateSelector.BoolTemplate>
<DataTemplate>
<controls:FastBoolCellView Height="24" Margin="0,0,10,0"
Expand Down
13 changes: 10 additions & 3 deletions WDE.DatabaseEditors/Data/DatabaseTableModelGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using WDE.Common.Database;
using WDE.Common.Services.MessageBox;
using WDE.DatabaseEditors.Data.Interfaces;
using WDE.DatabaseEditors.Data.Structs;
Expand Down Expand Up @@ -55,15 +56,16 @@ public DatabaseEntity CreateEmptyEntity(DatabaseTableDefinitionJson definition,
columns[column.DbColumnName] = databaseFieldFactory.CreateField(column.DbColumnName, valueHolder);
}

return new DatabaseEntity(false, key, columns);
return new DatabaseEntity(false, key, columns, null);
}

public IDatabaseTableData? CreateDatabaseTable(DatabaseTableDefinitionJson tableDefinition,
uint[] keys,
IList<Dictionary<string, (System.Type type, object value)>> fieldsFromDb)
{
HashSet<uint> providedKeys = new();


IList<IConditionLine>? conditions = null;
List<DatabaseEntity> rows = new();
foreach (var entity in fieldsFromDb)
{
Expand Down Expand Up @@ -112,6 +114,11 @@ public DatabaseEntity CreateEmptyEntity(DatabaseTableDefinitionJson definition,
{
valueHolder = new ValueHolder<long>(column.Value.value is DBNull ? 0 : ((bool)column.Value.value ? 1 : 0));
}
else if (column.Value.type == typeof(IList<IConditionLine>))
{
conditions = ((IList<IConditionLine>)column.Value.value);
continue;
}
else
{
throw new NotImplementedException();
Expand All @@ -129,7 +136,7 @@ public DatabaseEntity CreateEmptyEntity(DatabaseTableDefinitionJson definition,
columns[column.Key] = databaseFieldFactory.CreateField(column.Key, valueHolder);
}
if (key.HasValue)
rows.Add(new DatabaseEntity(true, key.Value, columns));
rows.Add(new DatabaseEntity(true, key.Value, columns, conditions?.ToList<ICondition>()));
}

if (!tableDefinition.IsMultiRecord)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using WDE.Common.Database;
using WDE.DatabaseEditors.Data.Structs;
using WDE.DatabaseEditors.Models;
using WDE.Module.Attributes;
Expand Down
3 changes: 3 additions & 0 deletions WDE.DatabaseEditors/Data/Structs/DatabaseColumnJson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ public class DatabaseColumnJson
[JsonProperty(PropertyName = "can_be_null")]
public bool CanBeNull { get; set; }

[JsonProperty(PropertyName = "is_condition")]
public bool IsConditionColumn { get; set; }

[JsonProperty(PropertyName = "preferred_width")]
public float? PreferredWidth { get; set; }
}
Expand Down
30 changes: 30 additions & 0 deletions WDE.DatabaseEditors/Data/Structs/DatabaseTableDefinitionJson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ public class DatabaseTableDefinitionJson
[JsonProperty(PropertyName = "primary_key")]
public IList<string>? PrimaryKey { get; set; }

[JsonProperty(PropertyName = "conditions")]
public DatabaseConditionReferenceJson? Condition { get; set; }

[JsonProperty(PropertyName = "foreign_tables")]
public IList<DatabaseForeignTableJson>? ForeignTable { get; set; }

Expand All @@ -64,4 +67,31 @@ public class DatabaseTableDefinitionJson
[JsonIgnore]
public IDictionary<string, DatabaseForeignTableJson> ForeignTableByName { get; set; } = null!;
}

public class DatabaseConditionReferenceJson
{
[JsonProperty(PropertyName = "source_type")]
public int SourceType { get; set; }

[JsonProperty(PropertyName = "source_group")]
public string? SourceGroupColumn { get; set; }

[JsonProperty(PropertyName = "source_entry")]
public string? SourceEntryColumn { get; set; }

[JsonProperty(PropertyName = "source_id")]
public string? SourceIdColumn { get; set; }

[JsonProperty(PropertyName = "targets")]
public IList<DatabaseConditionTargetJson>? Targets { get; set; }
}

public class DatabaseConditionTargetJson
{
[JsonProperty(PropertyName = "id")]
public uint Id { get; set; }

[JsonProperty(PropertyName = "name")]
public string Name { get; set; } = "";
}
}
20 changes: 20 additions & 0 deletions WDE.DatabaseEditors/DbDefinitions/gossip_menu_option.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,21 @@
"MenuID",
"OptionID"
],
"conditions": {
"source_type": 15,
"source_group": "MenuID",
"source_entry": "OptionID",
"targets": [
{
"id": 0,
"name": "player"
},
{
"id": 1,
"name": "gossip sender"
}
]
},
"groups": [
{
"group_name": "group",
Expand Down Expand Up @@ -70,6 +85,11 @@
"db_column_name": "ActionMenuID",
"value_type": "GossipMenuParameter"
},
{
"is_condition": true,
"name": "Conditions",
"db_column_name": "conditions"
},
{
"name": "Action Poi ID",
"db_column_name": "ActionPoiID",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.Collections.Generic;
using WDE.Common.Database;
using WDE.Common.History;
using WDE.DatabaseEditors.Models;

namespace WDE.DatabaseEditors.History
{
public class DatabaseEntityConditionsChangedHistoryAction : IHistoryAction
{
private readonly DatabaseEntity entity;
private readonly IReadOnlyList<ICondition>? oldConditions;
private readonly IReadOnlyList<ICondition>? newConditions;

public DatabaseEntityConditionsChangedHistoryAction(DatabaseEntity entity,
IReadOnlyList<ICondition>? oldConditions, IReadOnlyList<ICondition>? newConditions)
{
this.entity = entity;
this.oldConditions = oldConditions;
this.newConditions = newConditions;
}

public void Undo()
{
entity.Conditions = oldConditions;
}

public void Redo()
{
entity.Conditions = newConditions;
}

public string GetDescription()
{
return $"Entity {entity.Key} conditions changed";
}
}
}
46 changes: 45 additions & 1 deletion WDE.DatabaseEditors/Loaders/DatabaseTableDataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@ public class DatabaseTableDataProvider : IDatabaseTableDataProvider
private readonly ITableDefinitionProvider tableDefinitionProvider;
private readonly IMySqlExecutor sqlExecutor;
private readonly IMessageBoxService messageBoxService;
private readonly IDatabaseProvider databaseProvider;
private readonly IDatabaseTableModelGenerator tableModelGenerator;

public DatabaseTableDataProvider(ITableDefinitionProvider tableDefinitionProvider,
IMySqlExecutor sqlExecutor,
IMessageBoxService messageBoxService,
IDatabaseProvider databaseProvider,
IDatabaseTableModelGenerator tableModelGenerator)
{
this.tableDefinitionProvider = tableDefinitionProvider;
this.sqlExecutor = sqlExecutor;
this.messageBoxService = messageBoxService;
this.databaseProvider = databaseProvider;
this.tableModelGenerator = tableModelGenerator;
}

Expand All @@ -37,6 +40,7 @@ private string BuildSQLQueryFromTableDefinition(in DatabaseTableDefinitionJson t
var tablePrimaryKey = tableDefinitionJson.TablePrimaryKeyColumnName;
var columns = tableDefinitionJson.Groups
.SelectMany(x => x.Fields)
.Where(x => !x.IsConditionColumn)
.Select(x => $"`{x.ForeignTable ?? tableName}`.`{x.DbColumnName}`")
.Distinct();
var names = string.Join(",", columns);
Expand All @@ -59,14 +63,54 @@ private string BuildSQLQueryFromTableDefinition(in DatabaseTableDefinitionJson t
return null;

IList<Dictionary<string, (Type, object)>>? result = null;
IDatabaseProvider.ConditionKeyMask keyMask = IDatabaseProvider.ConditionKeyMask.None;
if (definition.Condition != null)
{
if (definition.Condition.SourceEntryColumn != null)
keyMask |= IDatabaseProvider.ConditionKeyMask.SourceEntry;
if (definition.Condition.SourceGroupColumn != null)
keyMask |= IDatabaseProvider.ConditionKeyMask.SourceGroup;
if (definition.Condition.SourceIdColumn != null)
keyMask |= IDatabaseProvider.ConditionKeyMask.SourceId;
}

if (keys.Length > 0)
{
var sqlStatement = BuildSQLQueryFromTableDefinition(definition, keys);

try
{
result = await sqlExecutor.ExecuteSelectSql(sqlStatement);

if (definition.Condition != null)
{
foreach (var row in result)
{
int? sourceGroup = null, sourceEntry = null, sourceId = null;

if (definition.Condition.SourceGroupColumn != null &&
row.TryGetValue(definition.Condition.SourceGroupColumn, out var groupData) &&
int.TryParse(groupData.Item2.ToString(), out var groupInt))
sourceGroup = groupInt;

if (definition.Condition.SourceEntryColumn != null &&
row.TryGetValue(definition.Condition.SourceEntryColumn, out var entryData) &&
int.TryParse(entryData.Item2.ToString(), out var entryInt))
sourceEntry = entryInt;

if (definition.Condition.SourceIdColumn != null &&
row.TryGetValue(definition.Condition.SourceIdColumn, out var idData) &&
int.TryParse(idData.Item2.ToString(), out var idInt))
sourceId = idInt;

var conditionList = await databaseProvider.GetConditionsForAsync(keyMask,
new IDatabaseProvider.ConditionKey(definition.Condition.SourceType, sourceGroup,
sourceEntry, sourceId));
if (conditionList?.Count > 0)
{
row.Add("conditions", (typeof(IList<IConditionLine>), conditionList));
}
}
}
}
catch (IMySqlExecutor.CannotConnectToDatabaseException e)
{
Expand Down
43 changes: 39 additions & 4 deletions WDE.DatabaseEditors/Models/DatabaseEntity.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,32 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using WDE.Common.Annotations;
using WDE.Common.Database;
using WDE.Common.History;
using WDE.DatabaseEditors.History;

namespace WDE.DatabaseEditors.Models
{
public class DatabaseEntity
public class DatabaseEntity : INotifyPropertyChanged
{
public Dictionary<string, IDatabaseField> Cells { get; }


private IReadOnlyList<ICondition>? conditions;

public IReadOnlyList<ICondition>? Conditions
{
get => conditions;
set
{
var old = conditions;
conditions = value;
OnAction?.Invoke(new DatabaseEntityConditionsChangedHistoryAction(this, old, value));
OnPropertyChanged();
}
}

public IEnumerable<IDatabaseField> Fields => Cells.Values;

public event System.Action<IHistoryAction>? OnAction;
Expand All @@ -15,11 +35,12 @@ public class DatabaseEntity

public uint Key { get; }

public DatabaseEntity(bool existInDatabase, uint key, Dictionary<string, IDatabaseField> cells)
public DatabaseEntity(bool existInDatabase, uint key, Dictionary<string, IDatabaseField> cells, IReadOnlyList<ICondition>? conditions)
{
ExistInDatabase = existInDatabase;
Key = key;
Cells = cells;
Conditions = conditions;
foreach (var databaseField in Cells)
{
databaseField.Value.OnChanged += action =>
Expand All @@ -41,7 +62,21 @@ public DatabaseEntity Clone()
var fields = new Dictionary<string, IDatabaseField>();
foreach (var field in Cells)
fields[field.Key] = field.Value.Clone();
return new DatabaseEntity(ExistInDatabase, Key, fields);

return new DatabaseEntity(ExistInDatabase, Key, fields, Conditions == null ? null : CloneConditions(Conditions));
}

private IReadOnlyList<ICondition> CloneConditions(IReadOnlyList<ICondition> conditions)
{
return conditions.Select(c => new AbstractCondition(c)).ToList<ICondition>();
}

public event PropertyChangedEventHandler? PropertyChanged;

[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Loading

0 comments on commit 004fde7

Please sign in to comment.