Misc

Table of content

Events

Events let use listen to database changes, like changing the field or entity, adding or removing entities.

How to use?

Add your listeners, like this

    private void AddListeners()
    {
        var events = BGRepo.I.Events;

        //listen to particular entity (row)
        events.AddEntityUpdatedListener(new BGId("some-entity-id"), EntityUpdated);
        events.AddEntityDeletedListener(new BGId("some-entity-id"), EntityDeleted);

        //listen to all entities (rows)
        events.AddAnyEntityAddedListener(new BGId("some-meta-id"), SomeEntityAdded);
        events.AddAnyEntityDeletedListener(new BGId("some-meta-id"), SomeEntityDeleted);
        events.AddAnyEntityUpdatedListener(new BGId("some-meta-id"), SomeEntityUpdated);

        //listen to some field change
        events.AddFieldListener(new BGId("some-field-id"), FieldChanged);
    }

    //------------------------------------------------
    //            Field changed
    //------------------------------------------------
    private void FieldChanged(object sender, BGEventArgsField e)
    {
        Debug.Log("The Field is changed " + e.Entity.Name);
    }

    //------------------------------------------------
    //             any entity (row)
    //------------------------------------------------
    private void SomeEntityUpdated(object sender, BGEventArgsAnyEntityUpdated e)
    {
        Debug.Log("Some Entity Updated " + e.Entity.Name);
    }

    private void SomeEntityDeleted(object sender, BGEventArgsAnyEntity e)
    {
        Debug.Log("Some Entity Deleted " + e.Entity.Id);
    }

    private void SomeEntityAdded(object sender, BGEventArgsAnyEntity e)
    {
        //note, fields are not available here
        Debug.Log("Some Entity Added " + e.Entity.Id);
    }

    //------------------------------------------------
    //             particular entity (row)
    //------------------------------------------------
    private void EntityDeleted(object sender, BGEventArgsEntity e)
    {
        Debug.Log("The Entity Deleted " + e.Entity.Id);
    }

    private void EntityUpdated(object sender, BGEventArgsEntityUpdated e)
    {
        Debug.Log("The Entity Updated " + e.Entity.Name);
    }

Do not forget to remove listeners, as soon as they are not needed. For example in you MonoBehaviour classes, use OnDestroy method to remove listeners.

Use corresponding events.RemoveXXX method to remove a listener.

Validation

Data validation allows to set the rules to validate data. Validation works in Unity Editor only and has no effect at runtime. To turn on validation, press on "Validation off" button at the top left of BGDatabase window.

Validation types
  1. Database data validation
  2. Scene objects validation (Binders and BGEntityGo components)
Database data validation
Validation rule Description
Entity name is unique If entity has a name, it should be unique
Entity name is empty Entities should have no name (names can be cleared under Configuration tab)
Entity is singleton Only one single entity should exist
Field is required Field should have some value. Only class-based fields are affected, cause struct-based fields always have a value
Key is unique Each key, marked as unique, should have 0-1 matching rows. If there are more than 1 matching row, it's considered to be a rule violation.

To review validation log, hover over red E icons as shown on the screenshot below. E icon is shown only if at least one error exists.

Scene objects validation

Following BGDatabase scene components can also be validated (using Scene Explorer tab).

  1. BGEntityGo components
  2. Generated Monobehaviour classes (extending from BGEntityGo)
  3. Data binders

Any component, which has an error, will be highlighted.

Custom keys

Custom key is a user defined key, which can be used to read row(s) quickly. It also can be used in rows validation

Each key consist of 1-n fields and can be marked as unique. Following fields can be added to a key: bool, int, long, decimal, bool?, int?, long?, string, text, enum, relationSingle.

You can access the matching row(s) directly without searching, using BGKey class or generated methods. To access the key use BGMetaEntity.GetKey({keyName}) method.

Keys make row(s) access faster, but uses extra memory and may slow down write (update) operations significantly, so do not use keys for data, which is updated frequently.

Command Line

Command line utility (Settings->Command line) let you run DDL-like commands with simplified syntax.

Syntax is (use empty line to separate commands):

    COMMAND [Options]
    [Additional options]

Available commands:

  1. CREATE TABLE [TableName]
    [FieldName] [FieldType]
  2. ALTER TABLE [TableName]
    ADD [FieldName] [FieldType]
    DROP [FieldName]
  3. DROP TABLE [TableName]

Example:

    CREATE TABLE MyTable
    MyField1 int
    MyField2 bool

    ALTER TABLE MyTable
    ADD MyField3 int
    DROP MyField1

    DROP TABLE MyTable

Custom fields implementation guide

  1. Do not use custom fields unless all other alternatives are much worse. For example, if your custom field has two properties (int and float) there is no need to create a custom field, you can use two basic fields instead (int and float) to store the values.
  2. Do not try to create your custom field in your actual project. Create and test your custom field using a new, empty project. Make sure it works correctly before transferring this field to your project. A bug in your implementation can break the whole database
  3. Use existing fields implementations as examples. Fields implementation sources can be found in Assets\BansheeGz\BGDatabase\Scripts\BGDatabaseSourceCode.unitypackage package (Database\Field\*). Fields managers implementation sources can be found in Assets\BansheeGz\BGDatabase\Editor\Scripts\BGDatabaseEditorSourceCode.unitypackage package (Database\Field\*).
  4. To create a custom field you need to create two C# classes:
    1. Class for the field (in runtime assembly)
    2. Class for the field's manager (in Editor assembly)
  5. [Important] Do not try to create your classes from scratch, extend them from existing classes.
    For your field class:
    1. If your field value is a class extend your field class from BGFieldCachedClassA class
    2. If your field value is a struct extend your field class from BGFieldCachedStructA class
    For your field's manager class:
    1. If your field value can be edited "in place" (like primitive fields: int, float, string)- extend your field's manager class from BGFieldManagerInlinedA class
    2. If your field value can be edited in popup window, which can be opened by clicking on cell button (like complex fields: bounds, assets)- extend your field's manager class from BGFieldManagerWithButtonA class
  6. The methods/properties, which need to be implemented for your field class:
    1. ToBytes/FromBytes- for binary serialization
    2. ToString/FromString- for string serialization
    3. CreateFieldFactory- utility method for creating new fields
    4. Implement ICloneable interface for your value type if it's a class (not struct)
    5. ValueSize property if your value type is a struct
  7. If you have difficulties implementing your own custom field- contact us and send us full source code for your value type (class/struct). You can skip its methods but all fields which needs to be saved inside database need to be included.