コード例 #1
0
        /// <summary>
        ///     Executes the filter action asynchronously.
        /// </summary>
        /// <param name="actionContext">The action context.</param>
        /// <param name="cancellationToken">The cancellation token assigned for this task.</param>
        /// <param name="continuation">The delegate function to continue after the action method is invoked.</param>
        /// <returns>
        ///     The newly created task for this operation.
        /// </returns>
        public Task <HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func <Task <HttpResponseMessage> > continuation)
        {
            // Get web context
            string entryPoint = "Failed";

            try
            {
                entryPoint = actionContext.ControllerContext.Controller.GetType( ).Name + "." + actionContext.ActionDescriptor.ActionName;
            }
            catch { }

            using (DatabaseContextInfo.SetContextInfo($"WebApi - {actionContext.ControllerContext.ControllerDescriptor.ControllerName}.{actionContext.ActionDescriptor.ActionName}"))
                using (EntryPointContext.SetEntryPoint(entryPoint))
                {
                    ProcessMonitorWriter.Instance.Write(entryPoint);

                    RequestContext requestContext = RequestContext.GetContext( );
                    if (requestContext != null && requestContext.IsValid)
                    {
                        // Attach timezone
                        string tz = HttpContext.Current.Request.Headers.Get("Tz");
                        if (!string.IsNullOrEmpty(tz))
                        {
                            // Set the timezone in the logical context
                            var contextData = new RequestContextData(requestContext.Identity, requestContext.Tenant, requestContext.Culture, tz);
                            RequestContext.SetContext(contextData);
                        }
                    }

                    // Do the actual API call work
                    return(continuation( ));
                }
        }
コード例 #2
0
        /// <summary>
        /// Set a value into secured data.
        /// </summary>
        /// <param name="tenantId">The tenant Id</param>
        /// <param name="context">A string representing the context of the storage.</param>
        /// <param name="secureId">The secured Id as proved by the Set call.</param>
        /// <param name="value">The value to be stored</param>
        public void Update(Guid secureId, string value)
        {
            if (secureId == Guid.Empty)
            {
                throw new ArgumentException(nameof(secureId));
            }

            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            long userId;

            RequestContext.TryGetUserId(out userId);

            using (DatabaseContextInfo.SetContextInfo("Update secure data"))
                using (DatabaseContext ctx = DatabaseContext.GetContext( ))
                {
                    using (IDbCommand command = ctx.CreateCommand("spSecuredDataUpdate", CommandType.StoredProcedure))
                    {
                        ctx.AddParameter(command, "@secureId", DbType.Guid, secureId);
                        ctx.AddParameter(command, "@data", DbType.String, value);
                        ctx.AddParameter(command, "@context", DbType.AnsiString, DatabaseContextInfo.GetMessageChain(userId));

                        var rows = command.ExecuteNonQuery( );

                        if (rows < 1)
                        {
                            throw new SecureIdNotFoundException($"Key not present. secureId: '{secureId}'");
                        }
                    }
                }
        }
コード例 #3
0
        /// <summary>
        ///     Setups the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        void IDataTarget.Setup(IProcessingContext context)
        {
            context?.WriteInfo("Initializing...");

            long userId;

            RequestContext.TryGetUserId(out userId);

            using (EntryPointContext.UnsafeToIncludeEntryPoint( ))
                using (IDbCommand command = CreateCommand( ))
                {
                    command.CommandText = CommandText.TenantRepairTargetSetupCommandText;
                    command.CommandType = CommandType.Text;
                    command.ExecuteNonQuery( );

                    command.CommandText = @"
IF ( @context IS NOT NULL )
BEGIN
	DECLARE @contextInfo VARBINARY(128) = CONVERT( VARBINARY(128), @context )
	SET CONTEXT_INFO @contextInfo
END";
                    command.AddParameter("@context", DbType.AnsiString, DatabaseContextInfo.GetMessageChain(userId), 128);
                    command.ExecuteNonQuery( );
                }
        }
コード例 #4
0
        public void TestNull( )
        {
            /////
            // Use stack trace
            /////
            string message = DatabaseContextInfo.GetMessageChain(0);

            Assert.AreEqual("u:0,DatabaseContextInfoTests.TestNull", message);
        }
コード例 #5
0
        public void TestMessageWithSingleValueThatFallsBelowTheMaximumLength( )
        {
            using (DatabaseContextInfo.SetContextInfo(TestString1))
            {
                string message = DatabaseContextInfo.GetMessageChain(0);

                Assert.AreEqual($"u:0,{TestString1}", message);
            }
        }
コード例 #6
0
        public void TestMessageWithSingleValueThatExceedTheMaximumLength( )
        {
            using (DatabaseContextInfo.SetContextInfo(TestString1.PadRight(MaxLength - 3, '!')))
            {
                string message = DatabaseContextInfo.GetMessageChain(0);

                Assert.AreEqual("u:0,The quick brown fox jumps over the lazy dog!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!...", message);
            }
        }
コード例 #7
0
        public void TestMessageWithSingleValueThatEqualsTheMaximumLength( )
        {
            using (DatabaseContextInfo.SetContextInfo(TestString1.PadRight(MaxLength - 4, '!')))
            {
                string message = DatabaseContextInfo.GetMessageChain(0);

                Assert.AreEqual($"u:0,{TestString1.PadRight( MaxLength - 4, '!' )}", message);
            }
        }
コード例 #8
0
        /// <summary>
        /// Updates the user accounts last logon time.
        /// </summary>
        /// <param name="entityId">The entity identifier.</param>
        /// <remarks>
        /// This intentionally bypasses the entity model and directly updates the database asynchronously.
        /// Any cached values are removed from the read-only cache upon completion.
        /// Cache invalidators are not invoked due to this call.
        /// </remarks>
        private static void UpdateUserAccountLastLogon(long entityId)
        {
            long     tenantId = RequestContext.TenantId;
            long     fieldId  = WellKnownAliases.CurrentTenant.LastLogon;
            DateTime now      = DateTime.UtcNow;

            ThreadPool.QueueUserWorkItem(state =>
            {
                using (DatabaseContextInfo.SetContextInfo($"Update last logon for user '{entityId}'"))
                    using (DatabaseContext ctx = DatabaseContext.GetContext( ))
                    {
                        using (var command = ctx.CreateCommand("spData_DateTimeMerge", CommandType.StoredProcedure))
                        {
                            ctx.AddParameter(command, "@entityId", DbType.Int64, entityId);
                            ctx.AddParameter(command, "@tenantId", DbType.Int64, tenantId);
                            ctx.AddParameter(command, "@fieldId", DbType.Int64, fieldId);
                            ctx.AddParameter(command, "@data", DbType.DateTime, now);
                            ctx.AddParameter(command, "@context", DbType.AnsiString, DatabaseContextInfo.GetMessageChain(entityId));

                            command.ExecuteNonQuery( );

                            IEntityFieldValues values;

                            /////
                            // Remove the last logon time from the field cache (if it exists).
                            /////
                            if (EntityFieldCache.Instance.TryGetValue(entityId, out values))
                            {
                                object lastLogon;

                                if (values.TryGetValue(fieldId, out lastLogon))
                                {
                                    values [fieldId] = now;
                                }
                            }

                            /////
                            // Invalidate any items referencing the LastLogon item (NOT the UserAccount item)
                            ////
                            var cacheInvalidators = new CacheInvalidatorFactory( ).CacheInvalidators.ToList( );

                            List <IEntity> fieldTypes = new List <IEntity>
                            {
                                new IdEntity(fieldId)
                            };

                            foreach (ICacheInvalidator cacheInvalidator in cacheInvalidators)
                            {
                                cacheInvalidator.OnEntityChange(fieldTypes, InvalidationCause.Save, null);
                            }
                        }
                    }
            });
        }
コード例 #9
0
        public void TestMessageContainsTwoValuesWithTheLastValueTruncated( )
        {
            using (DatabaseContextInfo.SetContextInfo("Hi"))
            {
                using (DatabaseContextInfo.SetContextInfo("HelloThereWorld"))
                {
                    string message = DatabaseContextInfo.GetMessageChain(0, "->", 20);

                    Assert.AreEqual("u:0,Hi->HelloTher...", message);
                }
            }
        }
コード例 #10
0
        public void TestEmpty( )
        {
            using (DatabaseContextInfo.SetContextInfo(string.Empty))
            {
                /////
                // Use CallerMemberName
                /////
                string message = DatabaseContextInfo.GetMessageChain(0);

                Assert.AreEqual("u:0,TestEmpty", message);
            }
        }
コード例 #11
0
        public void TestMessageWithMultipleValuesThatExceedTheMaximumLength( )
        {
            using (DatabaseContextInfo.SetContextInfo(TestString1.PadRight(MaxLength / 2 + 1, '!')))
            {
                using (DatabaseContextInfo.SetContextInfo(TestString2.PadRight(MaxLength / 2 + 1, '@')))
                {
                    string message = DatabaseContextInfo.GetMessageChain(0);

                    Assert.AreEqual("u:0,The quick brown fox jumps over the lazy dog!!!!!!!!!!!!!!...->The rain in spain stays mainly on the plain@@@@@@@@@@@@@@...", message);
                }
            }
        }
コード例 #12
0
        /// <summary>
        ///     Called when an entity field is saved.
        /// </summary>
        /// <param name="entity">The entity.</param>
        void IEntityFieldSave.OnSave(IEntity entity)
        {
            if (entity == null)
            {
                return;
            }

            long userId;

            RequestContext.TryGetUserId(out userId);

            /////
            // This is already running in a transaction
            /////
            using (DatabaseContext ctx = DatabaseContext.GetContext( ))
            {
                /////
                // Command takes an Update Lock under SERIALIZABLE isolation to ensure concurrency.
                /////
                using (DatabaseContextInfo.SetContextInfo("Update autonumber instance"))
                    using (IDbCommand command = ctx.CreateCommand("spUpdateAutoNumberInstance", CommandType.StoredProcedure))
                    {
                        ctx.AddParameter(command, "@entityId", DbType.Int64, entity.Id);
                        ctx.AddParameter(command, "@fieldId", DbType.Int64, _field.Id);
                        ctx.AddParameter(command, "@tenantId", DbType.Int64, RequestContext.TenantId);
                        ctx.AddParameter(command, "@context", DbType.AnsiString, DatabaseContextInfo.GetMessageChain(userId));

                        object newId = command.ExecuteScalar( );

                        if (newId != null && newId != DBNull.Value)
                        {
                            IEntityFieldValues readonlyFields;

                            /////
                            // Update the read-only cache with the new value.
                            /////
                            if (!EntityFieldCache.Instance.TryGetValue(entity.Id, out readonlyFields))
                            {
                                readonlyFields = new EntityFieldValues( );
                                EntityFieldCache.Instance[entity.Id] = readonlyFields;
                            }

                            /////
                            // Set the value.
                            /////
                            readonlyFields[_field.Id] = ( int )newId;
                        }
                    }
            }
        }
コード例 #13
0
        /// <summary>
        /// Creates or removes a permission relationship between a tenant and an app in the global tenant.
        /// </summary>
        private static void UpdateTenantPermissionRelationship(long tenantId, long appId, string relationshipAlias, bool grant)
        {
            const string grantSql = @"-- Grant app access
				IF ( @context IS NOT NULL )
				BEGIN
					DECLARE @contextInfo VARBINARY(128) = CONVERT( VARBINARY(128), @context )
					SET CONTEXT_INFO @contextInfo
				END

                declare @relId bigint = dbo.fnAliasNsId( @relAlias, 'core', default )
                if not exists ( select 1 from Relationship where TenantId = 0 and TypeId = @relId and FromId = @tenantId and ToId = @appId )
                begin
	                insert
		                into Relationship (TenantId, TypeId, FromId, ToId)
		                values (0, @relId, @tenantId, @appId)  
                end
                ";

            const string denySql = @"-- Deny app access
				IF ( @context IS NOT NULL )
				BEGIN
					DECLARE @contextInfo VARBINARY(128) = CONVERT( VARBINARY(128), @context )
					SET CONTEXT_INFO @contextInfo
				END

                declare @relId bigint = dbo.fnAliasNsId( @relAlias, 'core', default )
                delete from Relationship
                    where TenantId = 0 and TypeId = @relId and FromId = @tenantId and ToId = @appId
                ";

            long userId;

            RequestContext.TryGetUserId(out userId);

            using (DatabaseContextInfo.SetContextInfo("Update tenant permission relationship"))
                using (DatabaseContext ctx = DatabaseContext.GetContext( ))
                {
                    string sql = grant ? grantSql : denySql;

                    using (IDbCommand command = ctx.CreateCommand(sql))
                    {
                        ctx.AddParameter(command, "@relAlias", DbType.String, relationshipAlias);
                        ctx.AddParameter(command, "@tenantId", DbType.Int64, tenantId);
                        ctx.AddParameter(command, "@appId", DbType.Int64, appId);
                        ctx.AddParameter(command, "@context", DbType.AnsiString, DatabaseContextInfo.GetMessageChain(userId));

                        command.ExecuteNonQuery( );
                    }
                }
        }
コード例 #14
0
        public void TestMessageContainsMultipleValuesWithTheCenterValueDroppedAndTheLastValueTruncated( )
        {
            using (DatabaseContextInfo.SetContextInfo("Hi"))
            {
                using (DatabaseContextInfo.SetContextInfo("There"))
                {
                    using (DatabaseContextInfo.SetContextInfo("HelloWorld"))
                    {
                        string message = DatabaseContextInfo.GetMessageChain(0, "->", 20);

                        Assert.AreEqual("u:0,Hi->...->Hell...", message);
                    }
                }
            }
        }
コード例 #15
0
        /// <summary>
        ///     Reverts to.
        /// </summary>
        /// <param name="transactionId">The transaction identifier.</param>
        /// <param name="tenantId">The tenant identifier.</param>
        public static void RevertTo(long transactionId, long?tenantId = null)
        {
            string message = $"Reverting to transaction {transactionId}";

            if (tenantId >= 0)
            {
                message += $" for tenant {tenantId}";
            }

            long userId;

            RequestContext.TryGetUserId(out userId);

            try
            {
                using (DatabaseContextInfo info = new DatabaseContextInfo(message))
                    using (DatabaseContext ctx = DatabaseContext.GetContext( ))
                    {
                        using (IDbCommand command = ctx.CreateCommand("spRevertTo", CommandType.StoredProcedure))
                        {
                            ctx.AddParameter(command, "@transactionId", DbType.Int64, transactionId);

                            if (tenantId != null)
                            {
                                ctx.AddParameter(command, "@tenantId", DbType.Int64, tenantId);
                            }

                            ctx.AddParameter(command, "@context", DbType.AnsiString, DatabaseContextInfo.GetMessageChain(userId));

                            command.ExecuteNonQuery( );
                        }
                    }
            }
            finally
            {
                if (tenantId >= 0)
                {
                    TenantHelper.Invalidate(tenantId);
                }
            }

            AuditLogInstance.Get( ).OnTenantRollback(true, transactionId.ToString( ));
        }
コード例 #16
0
ファイル: AutoNumber.cs プロジェクト: hardin253874/Platform
        /// <summary>
        ///     Upgrades this instance.
        /// </summary>
        /// <param name="solutions">The solutions.</param>
        public static void Upgrade(IEnumerable <Solution> solutions)
        {
            long autoNumberValueId = WellKnownAliases.CurrentTenant.AutoNumberValue;

            long userId;

            RequestContext.TryGetUserId(out userId);

            /////
            // If the 'core:autoNumberValue' alias exists, convert all auto number instances
            // that are of the old type, regardless of solution that they belong to.
            /////

            using (DatabaseContext context = DatabaseContext.GetContext(true))
            {
                using (DatabaseContextInfo.SetContextInfo("Upgrade autonumber instances"))
                    using (var command = context.CreateCommand("spUpgradeAutoNumberInstance", CommandType.StoredProcedure))
                    {
                        context.AddParameter(command, "@tenantId", DbType.Int64, RequestContext.TenantId);
                        context.AddParameter(command, "@context", DbType.AnsiString, DatabaseContextInfo.GetMessageChain(userId));

                        command.ExecuteNonQuery( );
                    }

                using (DatabaseContextInfo.SetContextInfo("Upgrade autonumber start values"))
                    using (var command = context.CreateCommand("spUpgradeAutoNumberStartingNumber", CommandType.StoredProcedure))
                    {
                        context.AddParameter(command, "@tenantId", DbType.Int64, RequestContext.TenantId);
                        context.AddParameter(command, "@context", DbType.AnsiString, DatabaseContextInfo.GetMessageChain(userId));
                        var solutionIdParameter = context.AddParameter(command, "@solutionId", DbType.Int64);

                        foreach (Solution solution in solutions)
                        {
                            solutionIdParameter.Value = solution.Id;

                            command.ExecuteNonQuery( );
                        }
                    }

                context.CommitTransaction( );
            }
        }
コード例 #17
0
        /// <summary>
        ///     Deletes the tenant from the entity model.
        /// </summary>
        /// <param name="tenantId">The tenant id.</param>
        public static void DeleteTenant(long tenantId)
        {
            EventLog.Application.WriteWarning("Deleting tenant " + tenantId);

            long userId;

            RequestContext.TryGetUserId(out userId);

            using (DatabaseContext ctx = DatabaseContext.GetContext( ))
            {
                // Delete the tenant entity instance itself.
                // Note: this is stored in the root tenant
                using (new AdministratorContext( ))
                {
                    Entity.Delete(tenantId);
                }

                // Delete the data
                using (DatabaseContextInfo.SetContextInfo($"Delete tenant {tenantId}"))
                    using (IDbCommand command = ctx.CreateCommand("spDeleteTenant", CommandType.StoredProcedure))
                    {
                        ctx.AddParameter(command, "@tenantId", DbType.Int64, tenantId);
                        command.AddParameter("@context", DbType.AnsiString, DatabaseContextInfo.GetMessageChain(userId));

                        command.ExecuteNonQuery( );
                    }
            }

            /////
            // Remove the cached tenant id.
            /////
            List <string> matchingTenants = TenantIdCache.Where(pair => pair.Value == tenantId).Select(pair => pair.Key).ToList( );

            foreach (string matchingTenant in matchingTenants)
            {
                TenantIdCache.Remove(matchingTenant);
            }

            TenantNameCache.Remove(tenantId);

            EventLog.Application.WriteWarning("Deleted tenant " + tenantId);
        }
コード例 #18
0
        public void TestMessageContainsMultipleValuesWithNoValuesDropped( )
        {
            using (DatabaseContextInfo.SetContextInfo("One"))
            {
                using (DatabaseContextInfo.SetContextInfo("Two"))
                {
                    using (DatabaseContextInfo.SetContextInfo("Three"))
                    {
                        using (DatabaseContextInfo.SetContextInfo("Four"))
                        {
                            using (DatabaseContextInfo.SetContextInfo("Five"))
                            {
                                string message = DatabaseContextInfo.GetMessageChain(0);

                                Assert.AreEqual("u:0,One->Two->Three->Four->Five", message);
                            }
                        }
                    }
                }
            }
        }
コード例 #19
0
        /// <summary>
        ///     Creates the tenant.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="description">The description.</param>
        /// <returns></returns>
        public static long CreateTenant(string name, string description = null)
        {
            using (new GlobalAdministratorContext( ))
                using (DatabaseContextInfo.SetContextInfo($"Create tenant '{name}'"))
                {
                    /////
                    // Create the specified tenant
                    /////
                    var tenant = Entity.Create <Tenant>( );

                    tenant.Name        = name;
                    tenant.Description = description ?? name + " tenant";

                    if (name == "EDC")
                    {
                        tenant.Alias = "core:edcTenant";
                    }

                    tenant.Save( );

                    return(tenant.Id);
                }
        }
コード例 #20
0
        public void TestMessageContainsMultipleValuesWithMultipleCenterValuesDropped( )
        {
            using (DatabaseContextInfo.SetContextInfo("aa"))
            {
                using (DatabaseContextInfo.SetContextInfo("bb"))
                {
                    using (DatabaseContextInfo.SetContextInfo("cc"))
                    {
                        using (DatabaseContextInfo.SetContextInfo("dd"))
                        {
                            using (DatabaseContextInfo.SetContextInfo("ee"))
                            {
                                using (DatabaseContextInfo.SetContextInfo("ff"))
                                {
                                    string message = DatabaseContextInfo.GetMessageChain(0, "->", 20);

                                    Assert.AreEqual("u:0,aa->bb->...->ff", message);
                                }
                            }
                        }
                    }
                }
            }
        }
コード例 #21
0
        /// <summary>
        ///     Writes the specified audit log entry.
        /// </summary>
        /// <param name="entryData">The entry data.</param>
        /// <exception cref="System.ArgumentNullException">entryData</exception>
        public void Write(IAuditLogEntryData entryData)
        {
            if (entryData == null)
            {
                throw new ArgumentNullException(nameof(entryData));
            }

            using (DatabaseContextInfo.SetContextInfo("Write Audit Log"))
                using (new SecurityBypassContext())
                {
                    if (!CanWrite(entryData))
                    {
                        return;
                    }

                    IEntity logEntry = Entity.Create(entryData.AuditLogEntryType);

                    // Set type specific fields
                    foreach (var kvp in entryData.Parameters)
                    {
                        logEntry.SetField(kvp.Key, kvp.Value);
                    }

                    // Set base type fields and relationships
                    logEntry.SetField("name", entryData.AuditLogEntryType.Name);
                    logEntry.SetField("auditLogEntrySuccess", entryData.Success);
                    logEntry.SetField("auditLogEntryUser", entryData.UserName);
                    logEntry.SetField("auditLogEntryCreatedDate", entryData.CreatedDate);
                    logEntry.SetRelationships("auditLogEntrySeverity", new EntityRelationship <AuditLogSeverityEnum>(entryData.Severity).ToEntityRelationshipCollection(), Direction.Forward);
                    logEntry.SetField("auditLogEntryMessage", entryData.Message);

                    logEntry.Save();

                    _auditLogDeleter.Purge();
                }
        }
コード例 #22
0
        /// <summary>
        ///     Imports the tenant.
        /// </summary>
        /// <param name="packagePath">The package path.</param>
        /// <param name="tenantName">Name of the tenant.</param>
        /// <param name="overwrite">
        ///     if set to <c>true</c> [overwrite].
        /// </param>
        /// <param name="context">The context.</param>
        /// <exception cref="System.ArgumentNullException">tenantStorePath</exception>
        /// <exception cref="System.InvalidOperationException">
        ///     The package does not contain a tenant.
        ///     or
        /// </exception>
        /// <exception cref="System.ArgumentException">The package is corrupt.</exception>
        /// <remarks>
        ///     If a tenant with the same name already exists, an exception will be thrown.
        ///     To overwrite an existing tenant with the same name, call OverwriteTenant.
        /// </remarks>
        /// <returns>the tenant id</returns>
        private static long ImportTenant_Impl(string packagePath, string tenantName, bool overwrite, IProcessingContext context)
        {
            if (string.IsNullOrEmpty(packagePath))
            {
                throw new ArgumentNullException("packagePath");
            }

            if (context == null)
            {
                context = new ProcessingContext( );
            }

            context.Report.StartTime = DateTime.Now;

            try
            {
                /////
                // Create source to load app data from tenant
                /////
                using (var source = FileManager.CreateDataSource(packagePath))
                {
                    Metadata metadata = source.GetMetadata(context);

                    if (metadata.Type == SourceType.AppPackage)
                    {
                        throw new InvalidOperationException("The package does not contain a tenant.");
                    }

                    if (string.IsNullOrEmpty(tenantName))
                    {
                        tenantName = metadata.Name;
                    }

                    if (string.IsNullOrEmpty(tenantName))
                    {
                        throw new ArgumentException("The package is corrupt.");
                    }

                    bool deleteExistingTenant = false;

                    if (TenantExists(tenantName))
                    {
                        if (overwrite)
                        {
                            deleteExistingTenant = true;
                        }
                        else
                        {
                            throw new InvalidOperationException(string.Format("The tenant '{0}' already exists.", tenantName));
                        }
                    }

                    long userId;
                    RequestContext.TryGetUserId(out userId);

                    /////
                    // Create target to write to SQLite database
                    /////
                    using (var target = new TenantCopyTarget( ))
                    {
                        Tenant tenant;

                        /////
                        // Create the tenant.
                        /////
                        using (new GlobalAdministratorContext( ))
                        {
                            if (deleteExistingTenant)
                            {
                                Tenant existingTenant = Entity.GetByName <Tenant>(tenantName).FirstOrDefault( );

                                if (existingTenant != null)
                                {
                                    using (DatabaseContextInfo.SetContextInfo("Delete existing tenant"))
                                        using (IDbCommand command = target.CreateCommand( ))
                                        {
                                            command.CommandText = "spDeleteTenant";
                                            command.CommandType = CommandType.StoredProcedure;
                                            command.Parameters.Add(new SqlParameter("@tenantId", existingTenant.Id));
                                            command.AddParameter("@context", DbType.AnsiString, DatabaseContextInfo.GetMessageChain(userId));
                                            command.ExecuteNonQuery( );
                                        }
                                }
                            }

                            tenant             = Entity.Create <Tenant>( );
                            tenant.Name        = tenantName;
                            tenant.Description = tenantName + " tenant";
                            tenant.Save( );

                            target.TenantId = tenant.Id;
                        }

                        /////
                        // Copy the data
                        /////
                        var processor = new CopyProcessor(source, target, context);
                        processor.MigrateData( );

                        /////
                        // Commit the changes.
                        /////
                        target.Commit( );

                        return(tenant.Id);
                    }
                }
            }
            finally
            {
                ForeignKeyHelper.Trust( );

                context.Report.EndTime = DateTime.Now;
            }
        }
コード例 #23
0
        /// <summary>
        ///		Fixes the navigation section upgrade identifier.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="upgradeId">The upgrade identifier.</param>
        /// <param name="alias">The alias.</param>
        /// <param name="nameSpace">The name space.</param>
        private static void FixNavSectionUpgradeId(string name, Guid upgradeId, string alias, string nameSpace)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }

            if (upgradeId == Guid.Empty)
            {
                throw new ArgumentNullException("upgradeId");
            }

            if (string.IsNullOrEmpty(alias))
            {
                throw new ArgumentNullException("alias");
            }

            if (string.IsNullOrEmpty(nameSpace))
            {
                throw new ArgumentNullException("nameSpace");
            }

            try
            {
                const string commandText = @"-- Fix NavSection Update Id
DECLARE @name BIGINT = dbo.fnAliasNsId( 'name', 'core', @tenantId )
DECLARE @isOfType BIGINT = dbo.fnAliasNsId( 'isOfType', 'core', @tenantId )
DECLARE @navSection BIGINT = dbo.fnAliasNsId( 'navSection', 'console', @tenantId )
DECLARE @resourceInFolder BIGINT = dbo.fnAliasNsId( 'resourceInFolder', 'console', @tenantId )
DECLARE @topMenu BIGINT = dbo.fnAliasNsId( 'topMenu', 'console', @tenantId )
DECLARE @alias BIGINT = dbo.fnAliasNsId( 'alias', 'core', @tenantId )

DECLARE @entityId BIGINT

IF ( @context IS NOT NULL )
BEGIN
	DECLARE @contextInfo VARBINARY(128) = CONVERT( VARBINARY(128), @context )
	SET CONTEXT_INFO @contextInfo
END

SELECT
	@entityId = e.Id
FROM
	dbo.Entity e
JOIN
	dbo.Data_NVarChar n ON
		e.Id = n.EntityId
		AND e.TenantId = n.TenantId
		AND n.FieldId = @name
		AND n.Data_StartsWith = @targetName
JOIN
	dbo.Relationship t ON
		t.TenantId = n.TenantId
		AND t.TypeId = @isOfType
		AND t.FromId = n.EntityId
		AND t.ToId = @navSection
JOIN
	dbo.Relationship r ON
		r.TenantId = n.TenantId
		AND r.TypeId = @resourceInFolder
		AND r.FromId = n.EntityId
JOIN
	dbo.Relationship tt ON
		tt.TenantId = n.TenantId
		AND tt.TypeId = @isOfType
		AND tt.FromId = r.ToId
		AND tt.ToId = @topMenu
WHERE
	e.TenantId = @tenantId AND
	e.UpgradeId <> @upgradeId

IF ( @entityId IS NOT NULL )
BEGIN
	UPDATE
		dbo.Entity
	SET
		UpgradeId = @upgradeId
	WHERE
		Id = @entityId
		AND TenantId = @tenantId

	MERGE INTO
		[dbo].[Data_Alias] AS t
	USING ( 
		SELECT
			@entityId AS [EntityId],
			@tenantId AS [TenantId],
			@alias AS [FieldId],
			@targetAlias AS [Data],
			@targetNamespace AS [Namespace],
			0 AS [AliasMarkerId]
	) s ON s.EntityId = t.EntityId AND s.TenantId = t.TenantId AND s.FieldId = t.FieldId
	WHEN NOT MATCHED THEN
		INSERT ( [EntityId], [TenantId], [FieldId], [Data], [Namespace], [AliasMarkerId] )
		VALUES ( s.[EntityId], s.[TenantId], s.[FieldId], s.[Data], s.[Namespace], s.[AliasMarkerId] );
END";

                long userId;
                RequestContext.TryGetUserId(out userId);

                using (DatabaseContext ctx = DatabaseContext.GetContext())
                {
                    using (DatabaseContextInfo.SetContextInfo("Fix nav section upgrade id"))
                        using (var command = ctx.CreateCommand(commandText))
                        {
                            ctx.AddParameter(command, "@tenantId", System.Data.DbType.Int64, RequestContext.TenantId);
                            ctx.AddParameter(command, "@upgradeId", System.Data.DbType.Guid, upgradeId);
                            ctx.AddParameter(command, "@targetName", System.Data.DbType.String, name);
                            ctx.AddParameter(command, "@targetAlias", System.Data.DbType.String, alias);
                            ctx.AddParameter(command, "@targetNamespace", System.Data.DbType.String, nameSpace);
                            ctx.AddParameter(command, "@context", System.Data.DbType.AnsiString, DatabaseContextInfo.GetMessageChain(userId));

                            command.ExecuteNonQuery();
                        }
                }
            }
            catch (Exception exc)
            {
                EventLog.Application.WriteError("Failed to fix the navigation section '{0}'. {1}", name, exc);
            }
        }
コード例 #24
0
        /// <summary>
        /// Fixes the navigation section parent folder.
        /// </summary>
        /// <param name="child">The child.</param>
        /// <param name="parent">The parent.</param>
        private static void FixNavSectionParentFolder(Guid child, Guid parent)
        {
            try
            {
                const string commandText = @"-- Fix NavSection Parent Folder
DECLARE @resourceInFolder BIGINT = dbo.fnAliasNsId( 'resourceInFolder', 'console', @tenantId )

DECLARE @childId BIGINT
DECLARE @parentId BIGINT
DECLARE @currentParentId BIGINT

IF ( @context IS NOT NULL )
BEGIN
	DECLARE @contextInfo VARBINARY(128) = CONVERT( VARBINARY(128), @context )
	SET CONTEXT_INFO @contextInfo
END

SELECT
	@childId = Id
FROM
	Entity
WHERE
	TenantId = @tenantId
	AND UpgradeId = @child

IF ( @childId IS NULL )
BEGIN
	RETURN
END

SELECT
	@parentId = Id
FROM
	Entity
WHERE
	TenantId = @tenantId
	AND UpgradeId = @parent

IF ( @parentId IS NULL )
BEGIN
	RETURN
END

MERGE
	Relationship AS t
USING (
	SELECT
		@tenantId,
		@resourceInFolder,
		@childId )
	AS s (
		TenantId,
		TypeId,
		FromId )
	ON (
		s.TenantId = t.TenantId
		AND s.TypeId = t.TypeId
		AND s.FromId = t.FromId )
WHEN MATCHED AND ( t.ToId <> @parentId ) THEN
	UPDATE SET ToId = @parentId
WHEN NOT MATCHED THEN
	INSERT (TenantId, TypeId, FromId, ToId )
	VALUES ( @tenantId, @resourceInFolder, @childId, @parentId );"    ;

                long userId;
                RequestContext.TryGetUserId(out userId);

                using (DatabaseContextInfo.SetContextInfo("Fix nav section parent folder"))
                    using (DatabaseContext ctx = DatabaseContext.GetContext( ))
                    {
                        using (var command = ctx.CreateCommand(commandText))
                        {
                            ctx.AddParameter(command, "@tenantId", System.Data.DbType.Int64, RequestContext.TenantId);
                            ctx.AddParameter(command, "@child", System.Data.DbType.Guid, child);
                            ctx.AddParameter(command, "@parent", System.Data.DbType.Guid, parent);
                            ctx.AddParameter(command, "@context", System.Data.DbType.AnsiString, DatabaseContextInfo.GetMessageChain(userId));

                            command.ExecuteNonQuery( );
                        }
                    }
            }
            catch (Exception exc)
            {
                EventLog.Application.WriteError("Failed to fix the navigation section parent folder '{0}'. {1}", child.ToString("B"), exc);
            }
        }
コード例 #25
0
ファイル: SaveGraph.cs プロジェクト: hardin253874/Platform
        /// <summary>
        ///     Saves the specified CTX.
        /// </summary>
        /// <param name="context">The database context.</param>
        /// <returns>
        ///     A mapping of the old entity IDs to new entity IDs. If no cloning occurred,
        ///     this returns an empty dictionary.
        /// </returns>
        public IDictionary <long, long> Save(DatabaseContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            IDictionary <long, long> clonedIds = new Dictionary <long, long>( );

            using (DatabaseContextInfo dbContextInfo = DatabaseContextInfo.SetContextInfo("Save"))
                using (IDbCommand command = context.CreateCommand( ))
                {
                    command.CommandText = "dbo.spSaveGraphSave";
                    command.CommandType = CommandType.StoredProcedure;
                    command.AddParameter("@tenantId", DbType.Int64, RequestContext.TenantId);

                    PopulateInputEntitiesTable();

                    long userId;
                    RequestContext.TryGetUserId(out userId);

                    command.AddParameter("@context", DbType.AnsiString, DatabaseContextInfo.GetMessageChain(userId));
                    var transactionId = command.AddParameter("@transactionId", DbType.Int64);
                    transactionId.Direction = ParameterDirection.Output;

                    bool haveInputEntities  = AddInputEntitiesParameter(command);
                    bool haveClones         = AddEntityClonesParameters(command);
                    bool haveDeletions      = AddDeletionParameters(command);
                    bool haveAdditions      = AddAdditionParameters(command);
                    bool haveMiscStatements = AddMiscSqlStatementParameter(command);
                    bool haveChanges        = haveInputEntities || haveClones || haveDeletions || haveAdditions || haveMiscStatements;

                    if (!haveChanges)
                    {
                        return(clonedIds);
                    }

                    using (IDataReader reader = command.ExecuteReader( ))
                    {
                        /////
                        // Read mapping between temporary ids and persisted ids.
                        /////
                        while (reader.Read())
                        {
                            long oldId = reader.GetInt64(0);
                            long newId = reader.GetInt64(1);

                            Mapping[oldId] = newId;
                        }

                        /////
                        // If there were any clone operations, a separate result set containing the source
                        // and destination ids will be returned
                        /////
                        if (reader.NextResult())
                        {
                            while (reader.Read())
                            {
                                clonedIds[reader.GetInt64(0)] = reader.GetInt64(1);
                            }
                        }

                        /////
                        // Check for exceptions that occur AFTER the last expected result set is returned.
                        /////
                        if (reader.NextResult( ))
                        {
                            /////
                            // Exceptions thrown from Sql Server will appear as a separate result set when
                            // accessed using ExecuteReader. This means all results sets that occur before
                            // the failure condition will still be successfully returned. Must check for
                            // exceptions that occur AFTER the last EXPECTED result set has been returned.
                            /////
                        }
                    }

                    if (transactionId.Value != null && transactionId.Value != DBNull.Value)
                    {
                        dbContextInfo.TransactionId = ( long )transactionId.Value;
                    }
                }

            return(clonedIds);
        }