예제 #1
0
        /// <summary>
        /// For a given UnitOfWorkContext, perform a schema upgrade if necessary. The ordered set of revisions are executed from version+1 to version[n].
        /// </summary>
        /// <param name="unitOfWorkContext"> The target UnitOfWorkContext. </param>
        /// <returns> A value indicating whether any changes were needed against the target database (file). </returns>
        public bool PerformSchemaUpgrade(IUnitOfWorkContext unitOfWorkContext)
        {
            bool changed = false;
            DatabaseRevision revision;
            string svalue;
            int ivalue;
            int schemaRevision, currentSchemaRevision, recordsAffected;
            IList<IDictionary<string, object>> results;

            if ((object)unitOfWorkContext == null)
                throw new ArgumentNullException("unitOfWorkContext");

            if (this.Revisions.Count < 1)
                throw new InvalidOperationException("TODO (enhancement): add meaningful message");

            ivalue = unitOfWorkContext.FetchScalar<int>(CommandType.Text, this.DoesSchemaTrackingExistCommandText, null);

            if (ivalue != 1)
            {
                // revision -1
                schemaRevision = -1;
            }
            else
            {
                svalue = unitOfWorkContext.FetchScalar<string>(CommandType.Text, this.GetSchemaVersionCommandText, null);

                if (!DataType.TryParse(svalue, out schemaRevision))
                    throw new InvalidOperationException("TODO (enhancement): add meaningful message");
            }

            currentSchemaRevision = this.Revisions.Max(x => x.Number);

            if (schemaRevision != currentSchemaRevision)
            {
                changed = true;

                for (int workingRevision = schemaRevision + 1; workingRevision <= currentSchemaRevision; workingRevision++)
                {
                    int _workingRevision = workingRevision;

                    revision = this.Revisions.SingleOrDefault(rh => rh.Number == _workingRevision);

                    if ((object)revision == null)
                        throw new InvalidOperationException(String.Format("The revision number '{0}' was not found. Revsions must be sequential without any gaps.", _workingRevision));

                    if (revision.Statements.Count < 1)
                        throw new InvalidOperationException("A revsion must have at least one statement.");

                    foreach (string statement in revision.Statements)
                        unitOfWorkContext.ExecuteDictionary(CommandType.Text, statement, null, out recordsAffected);

                    results = unitOfWorkContext.ExecuteDictionary(CommandType.Text, this.IncrementSchemaVersionCommandText, null, out recordsAffected);

                    if (recordsAffected != 1)
                        throw new InvalidOperationException("TODO (enhancement): add meaningful message");
                }
            }

            ivalue = unitOfWorkContext.FetchScalar<int>(CommandType.Text, this.DoesSchemaTrackingExistCommandText, null);

            if (ivalue != 1)
                throw new InvalidOperationException("TODO (enhancement): add meaningful message");

            svalue = unitOfWorkContext.FetchScalar<string>(CommandType.Text, this.GetSchemaVersionCommandText, null);

            if (!DataType.TryParse(svalue, out schemaRevision))
                throw new InvalidOperationException("TODO (enhancement): add meaningful message");

            if (schemaRevision != currentSchemaRevision)
                throw new InvalidOperationException("TODO (enhancement): add meaningful message");

            return changed;
        }