// 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); }
/// <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; } } }
/// <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); } }
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); }
/// <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); }