Ejemplo n.º 1
0
        // returns the object array representing all the properties
        // from an EntityType with a particular primary key
        private object[] GetEntityQueryObjectsFromDatabase(
            string compositePrimaryKeyValues, IEntityType entityType, Func <byte[], IProperty, object> decoder)
        {
            var results = new object[entityType.Properties.Count];

            // HGETALL
            var redisHashEntries = UnderlyingDatabase.HashGetAll(
                ConstructRedisDataKeyName(entityType, compositePrimaryKeyValues))
                                   .ToDictionary(he => he.Name, he => he.Value);

            foreach (var property in entityType.Properties)
            {
                // Note: since null's are stored in the database as the absence of the column name in the hash
                // need to insert null's into the objectArryay at the appropriate places.
                RedisValue propertyRedisValue;
                if (redisHashEntries.TryGetValue(property.Name, out propertyRedisValue))
                {
                    results[property.Index] = decoder(propertyRedisValue, property);
                }
                else
                {
                    results[property.Index] = null;
                }
            }

            return(results);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Gets non-materialized values from database
        /// </summary>
        /// <param name="redisQuery">Query data to decide what is selected from the database</param>
        /// <returns>An Enumerable of non-materialized object[]'s each of which represents one primary key</returns>
        public virtual IEnumerable <object[]> GetResults([NotNull] RedisQuery redisQuery)
        {
            Check.NotNull(redisQuery, "redisQuery");

            var redisPrimaryKeyIndexKeyName =
                ConstructRedisPrimaryKeyIndexKeyName(redisQuery.EntityType);

            var allKeysForEntity = UnderlyingDatabase.SetMembers(redisPrimaryKeyIndexKeyName).AsEnumerable();

            return(allKeysForEntity
                   .Select(compositePrimaryKeyValue =>
                           GetProjectionQueryObjectsFromDatabase(compositePrimaryKeyValue, redisQuery.EntityType, redisQuery.SelectedProperties, DecodeBytes)));
        }
        protected async Task PersistAsync(IEnumerable <BatchStatement> statments, bool concurrencyCheck, Dictionary <string, object>[] objects, string entity, XElement keySchema)
        {
            ConnectionState state = Connection.State;

            try
            {
                if (state == ConnectionState.Closed)
                {
                    await Connection.OpenAsync();

                    Transaction = Connection.BeginTransaction();
                }

                foreach (BatchStatement statment in statments)
                {
                    string        sql        = statment.Sql;
                    DbParameter[] parameters = CreateParameters(statment.Parameters);
                    int           affected   = await UnderlyingDatabase.ExecuteSqlCommandAsync(sql, parameters);

                    CheckConcurrency(affected, sql, parameters, statment, concurrencyCheck, objects, entity, keySchema);
                }

                if (state == ConnectionState.Closed)
                {
                    if (Transaction != null)
                    {
                        Transaction.Commit();
                    }
                }
            }
            catch (Exception ex)
            {
                if (state == ConnectionState.Closed)
                {
                    if (Transaction != null)
                    {
                        Transaction.Rollback();
                    }
                }

                throw ex;
            }
            finally
            {
                if (state == ConnectionState.Closed)
                {
                    Connection.Close();
                    Transaction = null;
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Gets values from database and materializes new EntityTypes
        /// </summary>
        /// <typeparam name="TResult">type of expected result</typeparam>
        /// <param name="entityType">EntityType of </param>
        /// <returns>An Enumerable of materialized EntityType objects</returns>
        public virtual IEnumerable <TResult> GetMaterializedResults <TResult>([NotNull] IEntityType entityType)
        {
            Check.NotNull(entityType, "entityType");

            var redisPrimaryKeyIndexKeyName =
                ConstructRedisPrimaryKeyIndexKeyName(entityType);

            var allKeysForEntity = UnderlyingDatabase.SetMembers(redisPrimaryKeyIndexKeyName);

            foreach (var compositePrimaryKeyValues in allKeysForEntity)
            {
                var objectArrayFromHash =
                    GetEntityQueryObjectsFromDatabase(compositePrimaryKeyValues, entityType, DecodeBytes);
                var stateEntry = Configuration.StateManager.GetOrMaterializeEntry(
                    entityType, new ObjectArrayValueReader(objectArrayFromHash));
                yield return((TResult)stateEntry.Entity);
            }
        }
Ejemplo n.º 5
0
        public virtual async Task <int> SaveChangesAsync(
            [NotNull] IReadOnlyList <StateEntry> stateEntries,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            Check.NotNull(stateEntries, "stateEntries");

            if (cancellationToken.IsCancellationRequested)
            {
                return(0);
            }

            var entitiesProcessed = 0;
            var transaction       = UnderlyingDatabase.CreateTransaction();

            foreach (var entry in stateEntries)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(0);
                }

                switch (entry.EntityState)
                {
                case EntityState.Added:
                    AddInsertEntryCommands(transaction, entry);
                    break;

                case EntityState.Deleted:
                    AddDeleteEntryCommands(transaction, entry);
                    break;

                case EntityState.Modified:
                    AddModifyEntryCommands(transaction, entry);
                    break;
                }

                if (await transaction.ExecuteAsync())
                {
                    entitiesProcessed = stateEntries.Count;
                }
            }

            return(entitiesProcessed);
        }
Ejemplo n.º 6
0
        /// <returns>
        /// returns the object[] representing the set of selected properties from
        /// an EntityType with a particular primary key
        /// </returns>
        private object[] GetProjectionQueryObjectsFromDatabase(
            string primaryKey, IEntityType entityType,
            IEnumerable <IProperty> selectedProperties, Func <byte[], IProperty, object> decoder)
        {
            var selectedPropertiesArray = selectedProperties.ToArray();
            var results = new object[selectedPropertiesArray.Length];

            // HMGET
            var fields           = selectedPropertiesArray.Select(p => (RedisValue)p.Name).ToArray();
            var redisHashEntries = UnderlyingDatabase.HashGet(
                ConstructRedisDataKeyName(entityType, primaryKey), fields);

            for (int i = 0; i < selectedPropertiesArray.Length; i++)
            {
                results[i] = decoder(redisHashEntries[i], selectedPropertiesArray[i]);
            }

            return(results);
        }
        internal protected int Execute(InsertCommand <T> executeCommand, Modifier <T> modifier)
        {
            // establishing a relationship with parent
            if (executeCommand.ParentRelationship != null)
            {
                for (int i = 0; i < executeCommand.ParentRelationship.Properties.Length; i++)
                {
                    string parentProperty = executeCommand.ParentRelationship.Properties[i];
                    object value          = executeCommand.ParentPropertyValues[parentProperty];
                    string property       = executeCommand.ParentRelationship.RelatedProperties[i];
                    if (executeCommand.PropertyValues.ContainsKey(property))
                    {
                        executeCommand.PropertyValues[property] = value;
                    }
                    else
                    {
                        executeCommand.PropertyValues.Add(property, value);
                    }
                }
            }

            // Sequence
            foreach (XElement propertySchema in executeCommand.EntitySchema.Elements(SchemaVocab.Property).Where(p => p.Attribute(SchemaVocab.Sequence) != null))
            {
                if (propertySchema.Attribute(SchemaVocab.AutoIncrement) != null && propertySchema.Attribute(SchemaVocab.AutoIncrement).Value == "true")
                {
                    continue;
                }

                string propertyName = propertySchema.Attribute(SchemaVocab.Name).Value;

                // provided by user
                if (executeCommand.PropertyValues.ContainsKey(propertyName))
                {
                    if (executeCommand.PropertyValues[propertyName] != null)
                    {
                        continue;
                    }
                }

                string sequenceName = propertySchema.Attribute(SchemaVocab.Sequence).Value;

                string seq_sql  = ModificationGenerator.GenerateFetchSequenceStatement(sequenceName);
                object sequence = UnderlyingDatabase.ExecuteScalar(seq_sql);

                if (executeCommand.PropertyValues.ContainsKey(propertyName))
                {
                    executeCommand.PropertyValues[propertyName] = sequence;
                }
                else
                {
                    executeCommand.PropertyValues.Add(propertyName, sequence);
                }
                modifier.SetObjectValue(executeCommand.AggregNode, propertyName, sequence);
            }

            // non-ManyToMany
            if (executeCommand.EntitySchema.Attribute(SchemaVocab.Name).Value == executeCommand.Entity)
            {
                // patch up SetDefaultValues
                foreach (KeyValuePair <string, object> pair in executeCommand.PropertyValues)
                {
                    modifier.SetObjectValue(executeCommand.AggregNode, pair.Key, pair.Value);
                }
            }

            // raise inserting event
            InsertingEventArgs <T> args = new InsertingEventArgs <T>(executeCommand.AggregNode, executeCommand.Entity, executeCommand.Schema, executeCommand.Path, executeCommand.Aggreg);

            OnInserting(args);

            // non-ManyToMany
            if (executeCommand.EntitySchema.Attribute(SchemaVocab.Name).Value == executeCommand.Entity)
            {
                // synchronize propertyValues with modified aggregNode OnInserting
                SynchronizePropertyValues(executeCommand, modifier);
            }

            //
            modifier.CheckConstraints(executeCommand);

            // GenerateInsertStatement
            string sql = ModificationGenerator.GenerateInsertStatement(executeCommand.PropertyValues, executeCommand.EntitySchema,
                                                                       out IReadOnlyDictionary <string, object> dbParameterValues);

            DbParameter[] dbParameters = UnderlyingDatabase.CreateParameters(dbParameterValues);

            // AutoIncrement
            int      affected;
            XElement autoPropertySchema = executeCommand.EntitySchema.Elements(SchemaVocab.Property).FirstOrDefault(p =>
                                                                                                                    p.Attribute(SchemaVocab.AutoIncrement) != null && p.Attribute(SchemaVocab.AutoIncrement).Value == "true");

            if (autoPropertySchema == null)
            {
                affected = UnderlyingDatabase.ExecuteSqlCommand(sql, dbParameters);
            }
            else
            {
                affected = UnderlyingDatabase.ExecuteInsertCommand(sql, dbParameters, out object autoIncrementValue);

                string propertyName = autoPropertySchema.Attribute(SchemaVocab.Name).Value;
                if (executeCommand.PropertyValues.ContainsKey(propertyName))
                {
                    executeCommand.PropertyValues[propertyName] = autoIncrementValue;
                }
                else
                {
                    executeCommand.PropertyValues.Add(propertyName, autoIncrementValue);
                }

                // non-ManyToMany
                if (executeCommand.EntitySchema.Attribute(SchemaVocab.Name).Value == executeCommand.Entity)
                {
                    modifier.SetObjectValue(executeCommand.AggregNode, propertyName, autoIncrementValue);
                }
            }

            // raise inserted event
            InsertedEventArgs <T> args1 = new InsertedEventArgs <T>(executeCommand.AggregNode, executeCommand.Entity, executeCommand.Schema, executeCommand.Path, executeCommand.Aggreg);

            OnInserted(args1);

            foreach (SQLStatment statment in args1.After)
            {
                int i = UnderlyingDatabase.ExecuteSqlCommand(statment.Sql, statment.Parameters);
            }

            return(affected);
        }