Example #1
0
        private void ReleaseLockRecursively(bool forceRelease)
        {
            LoadAllChildren(false);
            foreach (Entity e in EnumerateAllChildren())
            {
                e.ReleaseLockRecursively(forceRelease);
            }

            if (!forceRelease)
            {
                CheckConcurrency();
            }

            string sql = "spReleaseEntityLock";

            using (SqlCommand cmd = Context.CreateStoredProcedureCommand(sql))
            {
                AppendBasicParameters(cmd);
                cmd.Parameters.Add("@LockOwner", SqlDbType.UniqueIdentifier).Value       = Context.ContextGuid;
                cmd.Parameters.Add("@ConcurrencyVersion", SqlDbType.Binary, 8).Direction = ParameterDirection.Output;
                cmd.Parameters.Add("RETVAL", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;

                cmd.ExecuteNonQuery();

                int retval = (int)cmd.Parameters["RETVAL"].Value;

                this.lockOwner          = Guid.Empty;
                this.concurrencyVersion = BitConverter.ToInt64((byte[])cmd.Parameters["@ConcurrencyVersion"].Value, 0);
            }

            Context.LogEvent(new Jhu.Graywulf.Logging.Event("Jhu.Graywulf.Registry.Entity.ReleaseLock", this.guid));
        }
Example #2
0
        /// <summary>
        /// Moves the entity up among its siblings.
        /// </summary>
        /// <remarks>
        /// Moves the entity up among its siblings by decreasing its <see cref="Number" /> property.
        /// All siblings are reorganized to keep the values of <b>Numbers</b> contigous.
        /// </remarks>
        public void Move(EntityMoveDirection direction)
        {
            string sql;

            if (direction == EntityMoveDirection.Up)
            {
                sql = "spMoveUpEntity";
            }
            else
            {
                sql = "spMoveDownEntity";
            }

            CheckConcurrency();

            using (SqlCommand cmd = Context.CreateStoredProcedureCommand(sql))
            {
                AppendBasicParameters(cmd);
                cmd.Parameters.Add("RETVAL", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;

                cmd.ExecuteNonQuery();

                var retval = (int)cmd.Parameters["RETVAL"].Value;

                if (retval >= 0)
                {
                    this.number = retval;
                }
            }

            Context.LogEvent(new Jhu.Graywulf.Logging.Event("Jhu.Graywulf.Registry.Entity.Move", this.guid));
        }
Example #3
0
        /// <summary>
        /// Check whether the entity was modified in the database since it was loaded.
        /// </summary>
        /// <remarks>
        /// Refer to the Developer's Guide about the optimistic concurrency model.
        /// The <see cref="Context" /> property must have a value of a valid object context with open database connection.
        /// </remarks>
        /// <exception cref="InvalidConcurrencyVersionException">Thrown when a potential concurrency issue is detected.</exception>
        /// <exception cref="LockingCollisionException">TODO</exception>
        protected void CheckConcurrency()
        {
            // TODO: implement locking for move operations (don't allow move if any locked)
            string sql = "spCheckEntityConcurrency";

            using (SqlCommand cmd = Context.CreateStoredProcedureCommand(sql))
            {
                AppendBasicParameters(cmd);
                cmd.Parameters.Add("@LockOwner", SqlDbType.UniqueIdentifier).Value   = Context.JobGuid;
                cmd.Parameters.Add("@ConcurrencyVersion", SqlDbType.Binary, 8).Value = BitConverter.GetBytes(this.concurrencyVersion);
                cmd.Parameters.Add("RETVAL", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;

                cmd.ExecuteNonQuery();

                int retval = (int)cmd.Parameters["RETVAL"].Value;

                if (retval < 0)
                {
                    Jhu.Graywulf.Logging.Event e = new Jhu.Graywulf.Logging.Event("Jhu.Graywulf.Registry.Entity.CheckConcurrency", this.guid);;
                    switch (retval)
                    {
                    case -1:
                        e.Message = LogMessages.InvalidConcurrencyVersion;
                        Context.LogEvent(e);
                        throw new InvalidConcurrencyVersionException();

                    case -2:
                        e.Message = LogMessages.LockingCollision;
                        Context.LogEvent(e);
                        throw new LockingCollisionException();
                    }
                }
            }
        }
Example #4
0
        private void DeleteRecursively(bool forceOverwrite)
        {
            LoadAllChildren(true);

            // Delete should go in reverse order in order to prevent
            // concurrency version exceptions
            foreach (Entity e in EnumerateAllChildren().Reverse <Entity>())
            {
                e.DeleteRecursively(forceOverwrite);
            }

            if (!forceOverwrite)
            {
                CheckConcurrency();
            }

            string sql = "spDeleteEntity";

            using (SqlCommand cmd = Context.CreateStoredProcedureCommand(sql))
            {
                AppendBasicParameters(cmd);
                cmd.Parameters.Add("@ConcurrencyVersion", SqlDbType.Binary, 8).Direction = ParameterDirection.Output;

                cmd.ExecuteNonQuery();

                this.concurrencyVersion = BitConverter.ToInt64((byte[])cmd.Parameters["@ConcurrencyVersion"].Value, 0);
                this.deleted            = true;
                this.dateDeleted        = DateTime.Now;
                this.userGuidDeleted    = Context.UserGuid;
            }

            Context.LogEvent(new Jhu.Graywulf.Logging.Event("Jhu.Graywulf.Registry.Entity.Delete", this.guid));
        }
Example #5
0
        /// <summary>
        /// Authenticate user
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        private User LoginUserInternal(Entity parent, string nameOrEmail, string password)
        {
            var user = new User(Context);

            // Load user from the database
            string sql = "spLoginUser";

            using (var cmd = Context.CreateStoredProcedureCommand(sql))
            {
                cmd.Parameters.Add("@ParentGuid", SqlDbType.UniqueIdentifier).Value = parent.Guid;
                cmd.Parameters.Add("@NameOrEmail", SqlDbType.NVarChar, 50).Value    = nameOrEmail;

                using (var dr = cmd.ExecuteReader())
                {
                    if (!dr.Read())
                    {
                        throw new EntityNotFoundException(ExceptionMessages.LoginFailed);
                    }

                    user.LoadFromDataReader(dr);
                }
            }

            // Compute password hash
            bool hashok = true;

            byte[] hash = User.ComputePasswordHash(password);

            // Compare the hash with the one in the database
            if (hash.Length != user.PasswordHash.Length)
            {
                hashok = false;
            }
            else
            {
                for (int i = 0; i < hash.Length; i++)
                {
                    if (hash[i] != user.PasswordHash[i])
                    {
                        hashok = false;
                        break;
                    }
                }
            }

            if (!hashok)
            {
                throw new SecurityException(ExceptionMessages.LoginFailed);
            }

            // Update context
            Context.UserGuid = user.Guid;
            Context.UserName = user.Name;

            Context.LogEvent(new Jhu.Graywulf.Logging.Event("Jhu.Graywulf.Registry.UserFactory.LoginUser", user.Guid));

            return(user);
        }
Example #6
0
        /// <summary>
        /// Modifies the already existing entity in the database.
        /// </summary>
        /// <remarks>
        /// The <see cref="Context" /> property must have a value of a valid object context with open database connection.
        /// </remarks>
        /// <param name="forceOverwrite">Determines if concurrency issues are ignored.</param>
        /// <exception cref="InvalidConcurrencyVersionException">
        /// Thrown when someone else modified the entity since it was loaded from the database.
        /// </exception>
        protected virtual void Modify(bool forceOverwrite)
        {
            if (!forceOverwrite)
            {
                CheckConcurrency();
            }

            // --- Modify record in the Entities table ---
            this.dateModified = DateTime.Now;

            string sql = "spModifyEntity";

            using (SqlCommand cmd = Context.CreateStoredProcedureCommand(sql))
            {
                AppendBasicParameters(cmd);
                cmd.Parameters.Add("@ConcurrencyVersion", SqlDbType.Binary, 8).Direction = ParameterDirection.Output;

                AppendEntityCreateModifyParameters(cmd);

                cmd.ExecuteNonQuery();

                this.concurrencyVersion = BitConverter.ToInt64((byte[])cmd.Parameters["@ConcurrencyVersion"].Value, 0);
            }

            // --- Modify record in the type specific table

            if (DBHelpers[this.GetType()].HasColumns)
            {
                using (var cmd = DBHelpers[this.GetType()].CreateUpdateCommand(this))
                {
                    AppendBasicParameters(cmd);
                    cmd.ExecuteNonQuery();
                }
            }

            Context.LogEvent(new Jhu.Graywulf.Logging.Event("Jhu.Graywulf.Registry.Entity.Modify", this.guid));
        }
Example #7
0
        /// <summary>
        /// Saves the newly created entity to the database.
        /// </summary>
        /// <remarks>
        /// This function is called by the <see cref="Save()"/> function of the <see cref="Entity" /> class
        /// through the <see cref="Create"/> function in the derived classes.
        /// The <see cref="Context" /> property must have a value of a valid object context with open database connection.
        /// </remarks>
        protected virtual void Create()
        {
            // Generate a new Guid for the entity
            guid = Guid.NewGuid();

            // --- Create record in the Entities table ---

            string sql = "spCreateEntity";

            using (var cmd = Context.CreateStoredProcedureCommand(sql))
            {
                AppendBasicParameters(cmd);
                cmd.Parameters.Add("@ConcurrencyVersion", SqlDbType.Binary, 8).Direction = ParameterDirection.Output;

                cmd.Parameters.Add("@ParentGuid", SqlDbType.UniqueIdentifier).Value = parentReference.Guid;
                cmd.Parameters.Add("@EntityType", SqlDbType.Int).Value = (int)EntityType;   // always use property
                cmd.Parameters.Add("@Number", SqlDbType.Int).Direction = ParameterDirection.Output;

                AppendEntityCreateModifyParameters(cmd);

                cmd.ExecuteNonQuery();

                // Read return values
                this.concurrencyVersion = BitConverter.ToInt64((byte[])cmd.Parameters["@ConcurrencyVersion"].Value, 0);
                this.number             = (int)cmd.Parameters["@Number"].Value;
            }

            using (var cmd = DBHelpers[this.GetType()].CreateInsertCommand(this))
            {
                AppendBasicParameters(cmd);
                cmd.ExecuteNonQuery();
            }

            isExisting = true;

            Context.LogEvent(new Jhu.Graywulf.Logging.Event("Jhu.Graywulf.Registry.Entity.Create", this.guid));
        }