FivePD API

Storing Custom Data (Variable Data)

FivePD includes a powerful and flexible data storage system. It allows addon developers to define, store, and manage custom data without needing to create or modify database tables. The system is based on the Entity-Attribute-Value (EAV) model, which provides great flexibility for defining custom data structures.

This is ideal for creating custom reports, logs, or any other data set your addon might need.

Currently, custom data sets are not editable via the in-game MDT. This functionality is reserved for official FivePD data sets like arrest and incident reports.

Core Concepts

  • VariableDataSet: This represents your custom data "table." You define it by creating a class that inherits from VariableDataSet and giving it a unique ID attribute.
  • VariableDataAttribute: These are the "columns" of your data set. You define the name, label, data type, and other properties for each piece of data you want to store.
  • VariableDataEntity: This is a single "row" or record within your data set.

There are two primary ways to create and manage your custom data sets.

1. Simple Registration with IVariableDataService

This method is quick and suitable for simple addons where you only need to define a data set and occasionally add records to it.

using FivePD.Server.Attributes;

// Make sure to write an id that is unique. You could add your name to it for example.
[VariableDataSetId("my_addon_set")]
public class MyAddonSet : VariableDataSet
{
}
using System.Collections.Generic;
using System.Threading.Tasks;
using FivePD.Server.API;
using FivePD.Server.Attributes;
using FivePD.Server.Interfaces.VariableData;
using FivePD.Server.Models.VariableData;

namespace MyAwesomeAddon;

public class MyExtension : IExtension
{
    private readonly IVariableDataService _variableDataService;

    public MyExtension(IVariableDataService variableDataService)
    {
        this._variableDataService = variableDataService;
        this._variableDataService.RegisterSetAttributes<MyAddonSet>(new List<VariableDataAttribute>
        {
            new()
            {
                Name = "Something",
                Label = "Something label",
                DataType = VariableDataType.Integer,
                Required = true,
                ShowInGrid = true,
                Readonly = false,
            },
        });
    }

    public Task OnStarted()
    {
        // Add an entity to your set
        var entity = this._variableDataService.AddEntity<MyAddonSet>(new VariableDataEntity
        {
            MappedValues = new Dictionary<string, object>
            {
                ["Something"] = 123,
            }
        });

        return Task.CompletedTask;
    }

    public Task OnStopped()
    {
        return Task.CompletedTask;
    }
}

2. Advanced Usage with a Custom Repository

This is the recommended approach for most addons. Creating a dedicated repository for your data set encapsulates all of your data logic in one place, provides strongly-typed methods, and allows you to easily handle data-related events.

using FivePD.Server.Attributes;

// Make sure to write an id that is unique.
[VariableDataSetId("my_addon_set")]
public class MyAddonSet : VariableDataSet
{
}
using System.Collections.Generic;
using FivePD.Server.Interfaces.Variable;
using FivePD.Server.Models.Variable;
using FivePD.Server.Services.Variable;

public class MyAddonSetRepository : VariableDataRepository<MyAddonSet>
{
    public MyAddonSetRepository(IVariableDataService variableDataService)
        : base(variableDataService)
    {
    }

    protected override List<VariableDataAttribute> RegisterSetAttributes()
    {
        return new List<VariableDataAttribute>
        {
            new()
            {
                Name = "Something",
                Label = "Something label",
                DataType = VariableDataType.Integer,
                Required = true,
                ShowInGrid = true,
                Readonly = false,
            },
        };
    }
}
using System.Collections.Generic;
using System.Threading.Tasks;
using FivePD.Server.API;
using FivePD.Server.Interfaces.VariableData;

namespace MyAwesomeAddon;

public class MyExtension : IExtension
{
    private readonly MyAddonSetRepository _myAddonSetRepository;

    public MyExtension(IVariableDataService variableDataService)
    {
        this._myAddonSetRepository = new MyAddonSetRepository(variableDataService);
        variableDataService.RegisterAddonRepository<MyAddonSet, MyAddonSetRepository>(this._myAddonSetRepository);
    }

    public Task OnStarted()
    {
        // Add an entity to your set using the repository
        var entity = this._myAddonSetRepository.Add(new()
        {
            MappedValues = new Dictionary<string, object>
            {
                ["Something"] = 123,
            }
        });

        return Task.CompletedTask;
    }

    public Task OnStopped()
    {
        return Task.CompletedTask;
    }
}