Skip to content
This repository has been archived by the owner on Oct 8, 2020. It is now read-only.

Maintenance

Daniel Wertheim edited this page Nov 29, 2012 · 27 revisions

NOTE! Ensure you have a backup of your DB and try it on a development environment first.

As of v11.0.0 there's a new maintenance API, which replaces Db.GetStructureSetMigrator. Available operations are:

  • Reset - Db.Maintenance.Reset();
  • RenameStructure - Db.Maintenance.RenameStructure("OldName", "NewName");
  • RegenerateQueryIndexesFor - Db.Maintenance.RegenerateQueryIndexesFor<T>()
  • Migrate - Db.Migrate<TFrom, TNew>(Func<TFrom, TTo, MigrationStatuses> modifier)
  • Migrate - Db.Migrate<TFrom, TTo>(Func<TFrom, TTo, MigrationStatuses> modifier)
  • Migrate - Db.Migrate<TFrom, TFromTemplate, TTo>(Func<TFrom, TTo, MigrationStatuses> modifier)

How to access the Maintenance API

Maintenance operations are accessible via Maintenance on a db-instance. Below is the documentation for all included operations.

Reset

Db. Maintenance.Reset() will look in the database for all tables ending with below suffixes; and then drop them:

  • Structure
  • Uniques
  • Integers
  • Fractals
  • Booleans
  • Dates
  • Guids
  • Strings
  • Texts

Important

All tables that has any of the above suffixes WILL BE DROPPED. Hence if you add a custom table, not being a SisoDb table, e.g "MyGoofyStrings"; it will also be dropped.

RenameStrucutre

Lets you rename a structure. E.g Db.Maintenance.Rename("Persons", "People") will rename included tables, primary keys, foreign keys etc.

RegenerateQueryIndexesFor

Will drop all existing query-indexes and regenerate them from the structures stored in db. E.g Db.Maintenance.RegenerateQueryIndexesFor<Person>()

Migrate

The migration operations lets you migrate data. Either from one model to another or within the same model. Hence, you could do migrations like:

  • Person --> SalePerson
  • Person --> Person

When doing migrations within the same type, e.g Person --> Person you don't even need to have the old-model at hand, since you can use the overload taking TFromTemplate. That way you could pass an anonymous type if you like. Otherwise, just have a migrations assembly and put the old model in there.

MigratorStatuses

The modifier can return three different values:

  • Keep: Indicates that you want to keep the structure and the new-structure will be persisted with the same id as the old.
  • Trash: Indicates that your are no longer interested in keeping the structure, hence it will be deleted.
  • Abort: Abort and rollback the process.

Rename structure

In this case you should really use Db.Maintenance.RenameStructure instead, but the migrations API will assist you with this as well. And if the new structure is compatible with the JSON you don't have to provide any manual mappings just return MigratorStatuses.Keep so that SisoDb will insert the new item in the new structureset.

(oldItem, newItem) => MigratorStatuses.Keep;

Rename properties

The TNew item has the new property and you will need to map it manually:

(oldItem, newItem) =>
{
    newItem.NewProperty = oldItem.OldPropery;
    return MigratorStatuses.Keep;
}

Split one property to several

I'll just let the example speak for it self.

Old model

public class Person //Change: Rename
{
    public Guid Id { get; set; }
    public string Name { get; set; } //Change: Split
    public string Address { get; set; } //Change: Split
    public string HairColor { get; set; } //Change: Drop
}

New model

public class SalesPerson
{
    public Guid Id { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public Address Office { get; set; }

    public SalesPerson()
    {
        Office = new Address();
    }
}

public class Address
{
    public string Street { get; set; }
    public string Zip { get; set; }
    public string City { get; set; }
}

Given

new Person
{
    Name = "Daniel Wertheim",
    Address = "The Street 1\r\n12345\r\nThe City",
    HairColor = "Black"
};

We want

new SalesPerson
{
    Firstname = "Daniel",
    Lastname = "Wertheim",
    Office = new Address
    {
        Street = "The Street 1",
        Zip = "12345",
        City = "The City"
    }
};

How-to do it using Func

db.Maintenance.Migrate<Person, SalesPerson>(
(p, sp) =>
{
    var names = p.Name.Split(' ');
    sp.Firstname = names[0];
    sp.Lastname = names[1];

    var address = p.Address
        .Split(new[]{"\r\n"}, StringSplitOptions.RemoveEmptyEntries);

    sp.Office.Street = address[0];
    sp.Office.Zip = address[1];
    sp.Office.City = address[2];

    return MigratorStatuses.Keep;
});

How-to do it using Migration

db.Maintenance.Migrate(Migrate<Person>.To<SalesPerson>().Using(
(p, sp) =>
{
    var names = p.Name.Split(' ');
    sp.Firstname = names[0];
    sp.Lastname = names[1];

    var address = p.Address
        .Split(new[]{"\r\n"}, StringSplitOptions.RemoveEmptyEntries);

    sp.Office.Street = address[0];
    sp.Office.Zip = address[1];
    sp.Office.City = address[2];

    return MigratorStatuses.Keep;
}));

Use anonymous objects in your migrations

By letting you use anonymous objects in your migrations you don't need to sit on an old representation of the model.

Old model

public class Car
{
    public string RegNo { get; set; } //Change: Rename
    public string Type { get; set; } //Change: Split
}

New model

public class Car
{
    public string RegistrationNumber { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
    public string Type { get; set; }
}

Given

new Car
{
    RegNo = "ABC123",
    Type = "Volvo V50 Deluxe"
}

We want

new Car
{
    RegistrationNumber = "ABC123",
    Make = "Volvo",
    Model = "V50",
    Type = "Deluxe"
}

How-to do it using Migration using anonymous object Note! In the code below Car is of the new model. The anonymous object represents the old model.

db.Maintenance.Migrate(Migrate<Car>.To<Car>().Using(
new
{
    RegNo = default(string),
    Type = default(string)
},
(oldItem, newItem) =>
{
    newItem.RegistrationNumber = oldItem.RegNo;

    var makeModelType = oldItem.Type.Split(' ');
    newItem.Make = makeModelType[0];
    newItem.Model = makeModelType[1];
    newItem.Type = makeModelType[2];

    return MigratorStatuses.Keep;
}));