예제 #1
0
        public override ICoreController Execute() {
            // 1. Create our migration controller 
            this.MigrationController = new MigrationController() {
                // 2. Tell the migration controller where it should send it's commands.
                BubbleObjects = {
                    // Pipe all commands to this controller, which is in turn passed onto Program.cs
                    // and eventually to Potato Database controller.
                    this
                },
                // 3. Setup a stream for us to track changes on.
                Settings = new MigrationSettings() {
                    Origin = MigrationOrigin.Plugin,
                    // This name should be unique to your plugin. You could even use your plugin GUID,
                    // but you might want to combine your guid with the connection guid, if you require
                    // migrations on a per-plugin, per-connection basis (a store for each connection)
                    Name = "Potato.Examples.Database"
                },
                // 4. Migrations are run in order in this list. You should append database changes onto
                // this chain *whenever* you make changes.
                // If you always ADD to this list then every release you have will automatically update
                // the database schematic, if the database being used requires a schematic.
                // A single migration is just executable code, so you can do any number of commands within
                // this migration. You could even do file structure changes in here if you wanted.
                Migrations = {
                    // Version 1.0.0.0
                    new Migration() {
                        // Up, moving upstream in changes.
                        Up = () => {
                            ICommandResult result = this.Bubble(
                                CommandBuilder.DatabaseQuery(
                                    new Create()
                                    // You should namespace/prefix your collections/tables to avoid clashes with other plugins
                                    .Collection("Potato_Example_Database_Users")
                                    .Modifier(new IfNotExists())
                                    .Field("Name", 255)
                                    .Field("Stamp", new DateTimeType())
                                )
                            );

                            return result.Now.Queries.First().DescendantsAndSelf<Error>().Any() == false;
                        },
                        // Down, moving downstream in changes (do the opposite of Up)
                        Down = () => {
                            // Including Down is not critical when moving upstream, but it's good
                            // practice to include Down. We may in the future include plugin uninstalling
                            // and down migrations would allow the database to be uninstalled.
                            ICommandResult result = this.Bubble(
                                CommandBuilder.DatabaseQuery(
                                    new Drop()
                                    .Collection("Potato_Example_Database_Users")
                                )
                            );

                            return result.Now.Queries.First().DescendantsAndSelf<Error>().Any() == false;
                        }
                    },
                    // Pretend you released 1.0.0.0, then released an update later
                    // Version 1.0.0.1
                    new Migration() {
                        Up = () => {
                            // Add another field to our example
                            ICommandResult result = this.Bubble(
                                CommandBuilder.DatabaseQuery(
                                    new Alter()
                                    .Collection("Potato_Example_Database_Users")
                                    .Method(
                                        new Create()
                                        .Field("Age", new IntegerType())
                                    )
                                )
                            );

                            return result.Now.Queries.First().DescendantsAndSelf<Error>().Any() == false;
                        },
                        Down = () => {
                            // Drop the field, so people can revert this migration or uninstall can go
                            // through the motions.
                            ICommandResult result = this.Bubble(
                                CommandBuilder.DatabaseQuery(
                                    new Alter()
                                    .Collection("Potato_Example_Database_Users")
                                    .Method(
                                        new Drop()
                                        .Field("Age", new IntegerType())
                                    )
                                )
                            );

                            return result.Now.Queries.First().DescendantsAndSelf<Error>().Any() == false;
                        }
                    }
                }
            };

            // 5. This will setup the basic migration tables if they do not exists already (your plugin
            // might be first to use migrations). You should always call Execute on a newly formed ExecutableBase anyway.
            this.MigrationController.Execute();

            // 6. Now run through the migrations until we are at the latest version.
            this.MigrationController.Up();

            return base.Execute();
        }
예제 #2
0
        public TestMigrationTrackerHelper() {
            Migrations = new MigrationController() {
                // Bubble all commands to the database controller
                BubbleObjects = new List<ICoreController>() {
                    TestDatabaseController.OpenSqLiteDriver()
                },
                Migrations = new List<IMigration>() {
                    new Migration() {
                        Up = () => {
                            Tracker = 1;

                            Counter++;

                            return true;
                        },
                        Down = () => {
                            Tracker = 0;

                            Counter++;

                            return true;
                        }
                    },
                    new Migration() {
                        Up = () => {
                            Tracker = 2;

                            Counter++;

                            return true;
                        },
                        Down = () => {
                            Tracker = 1;

                            Counter++;

                            return true;
                        }
                    },
                    new Migration() {
                        Up = () => {
                            Tracker = 3;

                            Counter++;

                            return true;
                        },
                        Down = () => {
                            Tracker = 2;

                            Counter++;

                            return true;
                        }
                    },
                    new Migration() {
                        Up = () => {
                            Tracker = 4;

                            Counter++;

                            return true;
                        },
                        Down = () => {
                            Tracker = 3;

                            Counter++;

                            return true;
                        }
                    }
                },
                Settings = new MigrationSettings() {
                    // Create a random stream name
                    Name = StringExtensions.RandomString(10),
                    // Just use Core as the origin for testing
                    Origin = MigrationOrigin.Core
                }
            }.Execute() as MigrationController;
        }
        public void TestMigrationUpFromNothingButCanceled() {
            int counter = 0;

            var migrations = new MigrationController() {
                // Bubble all commands to the database controller
                BubbleObjects = new List<ICoreController>() {
                    TestDatabaseController.OpenSqLiteDriver()
                },
                Migrations = new List<IMigration>() {
                    new Migration() {
                        Up = () => {
                            counter++;

                            return false;
                        },
                        Down = () => {
                            counter++;

                            return false;
                        }
                    }
                },
                Settings = new MigrationSettings() {
                    // Create a random stream name
                    Name = StringExtensions.RandomString(10),
                    // Just use Core as the origin for testing
                    Origin = MigrationOrigin.Core
                }
            };

            migrations.Execute();

            migrations.Up();

            Assert.AreEqual(1, counter);
            Assert.AreEqual(0, migrations.FindCurrentVersion());
        }