public bool Update(DbEntityRelation relation)
        {
            lock (lockObj)
            {
                if (relation == null)
                {
                    throw new ArgumentNullException("relation");
                }

                using (DbConnection con = DbContext.Current.CreateConnection())
                {
                    NpgsqlCommand command = con.CreateCommand("UPDATE entity_relations SET json=@json WHERE id=@id;");

                    JsonSerializerSettings settings = new JsonSerializerSettings {
                        TypeNameHandling = TypeNameHandling.Auto
                    };

                    var parameter = command.CreateParameter() as NpgsqlParameter;
                    parameter.ParameterName = "json";
                    parameter.Value         = JsonConvert.SerializeObject(relation, settings);
                    parameter.NpgsqlDbType  = NpgsqlDbType.Json;
                    command.Parameters.Add(parameter);

                    var parameterId = command.CreateParameter() as NpgsqlParameter;
                    parameterId.ParameterName = "id";
                    parameterId.Value         = relation.Id;
                    parameterId.NpgsqlDbType  = NpgsqlDbType.Uuid;
                    command.Parameters.Add(parameterId);

                    relationCache = new List <DbEntityRelation>();

                    return(command.ExecuteNonQuery() > 0);
                }
            }
        }
        public List <DbEntityRelation> Read()
        {
            lock (lockObj)
            {
                if (relationCache.Any())
                {
                    return(relationCache);
                }

                using (DbConnection con = DbContext.Current.CreateConnection())
                {
                    NpgsqlCommand command = con.CreateCommand("SELECT json FROM entity_relations;");

                    using (NpgsqlDataReader reader = command.ExecuteReader())
                    {
                        JsonSerializerSettings settings = new JsonSerializerSettings {
                            TypeNameHandling = TypeNameHandling.Auto
                        };
                        List <DbEntityRelation> relations = new List <DbEntityRelation>();
                        while (reader.Read())
                        {
                            DbEntityRelation relation = JsonConvert.DeserializeObject <DbEntityRelation>(reader[0].ToString(), settings);
                            relations.Add(relation);
                        }

                        reader.Close();

                        relationCache = new List <DbEntityRelation>(relations.ToArray());

                        return(relations);
                    }
                }
            }
        }
Beispiel #3
0
        public bool Create(DbEntity entity, Dictionary <string, Guid> sysldDictionary = null)
        {
            try
            {
                using (DbConnection con = DbContext.Current.CreateConnection())
                {
                    con.BeginTransaction();

                    try
                    {
                        List <DbParameter> parameters = new List <DbParameter>();

                        JsonSerializerSettings settings = new JsonSerializerSettings {
                            TypeNameHandling = TypeNameHandling.Auto
                        };

                        DbParameter parameterId = new DbParameter();
                        parameterId.Name  = "id";
                        parameterId.Value = entity.Id;
                        parameterId.Type  = NpgsqlDbType.Uuid;
                        parameters.Add(parameterId);

                        DbParameter parameterJson = new DbParameter();
                        parameterJson.Name  = "json";
                        parameterJson.Value = JsonConvert.SerializeObject(entity, settings);
                        parameterJson.Type  = NpgsqlDbType.Json;
                        parameters.Add(parameterJson);

                        string tableName = RECORD_COLLECTION_PREFIX + entity.Name;

                        DbRepository.CreateTable(tableName);
                        foreach (var field in entity.Fields)
                        {
                            bool      isPrimaryKey = field.Name.ToLowerInvariant() == "id";
                            FieldType fieldType    = field.GetFieldType();
                            DbRepository.CreateColumn(tableName, field.Name, fieldType, isPrimaryKey, field.GetDefaultValue(), !field.Required);
                        }

                        bool result = DbRepository.InsertRecord("entities", parameters);

                        if (!result)
                        {
                            throw new Exception("Entity record was not added!");
                        }

                        if (entity.Id != SystemIds.UserEntityId)
                        {
                            DbEntity userEntity = Read(SystemIds.UserEntityId);

                            DbRelationRepository relRep = new DbRelationRepository();

                            string createdByRelationName  = $"user_{entity.Name}_created_by";
                            string modifiedByRelationName = $"user_{entity.Name}_modified_by";

                            Guid createdByRelationId = Guid.NewGuid();
                            if (sysldDictionary != null && sysldDictionary.ContainsKey(createdByRelationName))
                            {
                                createdByRelationId = sysldDictionary[createdByRelationName];
                            }

                            Guid modifiedByRelationId = Guid.NewGuid();
                            if (sysldDictionary != null && sysldDictionary.ContainsKey(modifiedByRelationName))
                            {
                                modifiedByRelationId = sysldDictionary[modifiedByRelationName];
                            }

                            List <DbEntityRelation> relationList = relRep.Read();
                            DbEntityRelation        tempRel      = relationList.FirstOrDefault(r => r.Name == createdByRelationName);
                            if (tempRel != null)
                            {
                                createdByRelationId = tempRel.Id;
                                relRep.Delete(createdByRelationId);
                            }
                            tempRel = relationList.FirstOrDefault(r => r.Name == modifiedByRelationName);
                            if (tempRel != null)
                            {
                                modifiedByRelationId = tempRel.Id;
                                relRep.Delete(modifiedByRelationId);
                            }

                            DbEntityRelation createdByRelation = new DbEntityRelation();
                            createdByRelation.Id             = createdByRelationId;
                            createdByRelation.Name           = createdByRelationName;
                            createdByRelation.Label          = $"user<-[1]:[m]->{entity.Name}.created_by";
                            createdByRelation.RelationType   = EntityRelationType.OneToMany;
                            createdByRelation.OriginEntityId = SystemIds.UserEntityId;
                            createdByRelation.OriginFieldId  = userEntity.Fields.Single(f => f.Name == "id").Id;
                            createdByRelation.TargetEntityId = entity.Id;
                            createdByRelation.TargetFieldId  = entity.Fields.Single(f => f.Name == "created_by").Id;
                            {
                                bool res = relRep.Create(createdByRelation);
                                if (!res)
                                {
                                    throw new Exception("Creation of relation between User and Area entities failed!");
                                }
                            }

                            DbEntityRelation modifiedByRelation = new DbEntityRelation();
                            modifiedByRelation.Id             = modifiedByRelationId;
                            modifiedByRelation.Name           = modifiedByRelationName;
                            modifiedByRelation.Label          = "user<-[1]:[m]->area.last_modified_by";
                            modifiedByRelation.RelationType   = EntityRelationType.OneToMany;
                            modifiedByRelation.OriginEntityId = SystemIds.UserEntityId;
                            modifiedByRelation.OriginFieldId  = userEntity.Fields.Single(f => f.Name == "id").Id;
                            modifiedByRelation.TargetEntityId = entity.Id;
                            modifiedByRelation.TargetFieldId  = entity.Fields.Single(f => f.Name == "last_modified_by").Id;
                            {
                                bool res = relRep.Create(modifiedByRelation);
                                if (!res)
                                {
                                    throw new Exception($"Creation of relation between User and {entity.Name} entities failed!");
                                }
                            }
                        }
                        con.CommitTransaction();

                        return(result);
                    }
                    catch (Exception e)
                    {
                        con.RollbackTransaction();
                    }
                }
                return(false);
            }
            finally
            {
                Cache.Clear();
            }
        }
        public bool Delete(Guid relationId)
        {
            DbEntityRelation relation = Read(relationId);

            if (relation == null)
            {
                throw new StorageException("There is no record with specified relation id.");
            }

            List <DbEntity> entities = DbContext.Current.EntityRepository.Read();

            DbEntity originEntity = entities.FirstOrDefault(e => e.Id == relation.OriginEntityId);
            DbEntity targetEntity = entities.FirstOrDefault(e => e.Id == relation.TargetEntityId);

            DbBaseField originField = originEntity.Fields.FirstOrDefault(f => f.Id == relation.OriginFieldId);
            DbBaseField targetField = targetEntity.Fields.FirstOrDefault(f => f.Id == relation.TargetFieldId);

            string originTableName = $"rec_{originEntity.Name}";
            string targetTableName = $"rec_{targetEntity.Name}";

            try
            {
                using (DbConnection con = DbContext.Current.CreateConnection())
                {
                    con.BeginTransaction();

                    NpgsqlCommand command = con.CreateCommand("DELETE FROM entity_relations WHERE id=@id;");

                    var parameterId = command.CreateParameter() as NpgsqlParameter;
                    parameterId.ParameterName = "id";
                    parameterId.Value         = relationId;
                    parameterId.NpgsqlDbType  = NpgsqlDbType.Uuid;
                    command.Parameters.Add(parameterId);

                    try
                    {
                        command.ExecuteNonQuery();

                        if (originField.Name != "id")
                        {
                            DbRepository.DropIndex($"idx_r_{relation.Name}_{originField.Name}");
                        }
                        if (targetField.Name != "id")
                        {
                            DbRepository.DropIndex($"idx_r_{relation.Name}_{targetField.Name}");
                        }

                        if (relation.RelationType == EntityRelationType.ManyToMany)
                        {
                            DbRepository.DeleteNtoNRelation(relation.Name, originTableName, targetTableName);
                        }
                        else
                        {
                            DbRepository.DeleteRelation(relation.Name, targetTableName);
                        }

                        con.CommitTransaction();
                        return(true);
                    }
                    catch (Exception)
                    {
                        con.RollbackTransaction();
                    }
                }

                return(false);
            }
            finally
            {
                Cache.Clear();
            }
        }
        public bool Create(DbEntityRelation relation)
        {
            try
            {
                if (relation == null)
                {
                    throw new ArgumentNullException("relation");
                }

                List <DbParameter> parameters = new List <DbParameter>();

                JsonSerializerSettings settings = new JsonSerializerSettings {
                    TypeNameHandling = TypeNameHandling.Auto
                };

                DbParameter parameterId = new DbParameter();
                parameterId.Name  = "id";
                parameterId.Value = relation.Id;
                parameterId.Type  = NpgsqlDbType.Uuid;
                parameters.Add(parameterId);

                DbParameter parameterJson = new DbParameter();
                parameterJson.Name  = "json";
                parameterJson.Value = JsonConvert.SerializeObject(relation, settings);
                parameterJson.Type  = NpgsqlDbType.Json;
                parameters.Add(parameterJson);

                List <DbEntity> entities = DbContext.Current.EntityRepository.Read();

                DbEntity originEntity = entities.FirstOrDefault(e => e.Id == relation.OriginEntityId);
                DbEntity targetEntity = entities.FirstOrDefault(e => e.Id == relation.TargetEntityId);

                DbBaseField originField = originEntity.Fields.FirstOrDefault(f => f.Id == relation.OriginFieldId);
                DbBaseField targetField = targetEntity.Fields.FirstOrDefault(f => f.Id == relation.TargetFieldId);

                string originTableName = $"rec_{originEntity.Name}";
                string targetTableName = $"rec_{targetEntity.Name}";

                using (DbConnection con = DbContext.Current.CreateConnection())
                {
                    con.BeginTransaction();

                    try
                    {
                        bool result = DbRepository.InsertRecord("entity_relations", parameters);

                        if (relation.RelationType == EntityRelationType.ManyToMany)
                        {
                            DbRepository.DeleteNtoNRelation(relation.Name, originTableName, targetTableName);
                            DbRepository.CreateNtoNRelation(relation.Name, originTableName, originField.Name, targetTableName, targetField.Name);
                        }
                        else
                        {
                            DbRepository.DeleteRelation(relation.Name, targetTableName);
                            if (originField.Name != "id")
                            {
                                DbRepository.DropIndex($"idx_r_{relation.Name}_{originField.Name}");
                            }
                            if (targetField.Name != "id")
                            {
                                DbRepository.DropIndex($"idx_r_{relation.Name}_{targetField.Name}");
                            }

                            DbRepository.CreateRelation(relation.Name, originTableName, originField.Name, targetTableName, targetField.Name);
                            if (originField.Name != "id")
                            {
                                DbRepository.CreateIndex($"idx_r_{relation.Name}_{originField.Name}", originTableName, originField.Name);
                            }
                            if (targetField.Name != "id")
                            {
                                DbRepository.CreateIndex($"idx_r_{relation.Name}_{targetField.Name}", targetTableName, targetField.Name);
                            }
                        }

                        con.CommitTransaction();
                        return(true);
                    }
                    catch
                    {
                        con.RollbackTransaction();
                        throw;
                    }
                }
            }
            finally
            {
                Cache.Clear();
            }
        }
        public bool Create(DbEntity entity, Dictionary<string, Guid> sysldDictionary = null)
        {
            try
            {
                using (DbConnection con = DbContext.Current.CreateConnection())
                {
                    con.BeginTransaction();

                    try
                    {
                        List<DbParameter> parameters = new List<DbParameter>();

                        JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto };

                        DbParameter parameterId = new DbParameter();
                        parameterId.Name = "id";
                        parameterId.Value = entity.Id;
                        parameterId.Type = NpgsqlDbType.Uuid;
                        parameters.Add(parameterId);

                        DbParameter parameterJson = new DbParameter();
                        parameterJson.Name = "json";
                        parameterJson.Value = JsonConvert.SerializeObject(entity, settings);
                        parameterJson.Type = NpgsqlDbType.Json;
                        parameters.Add(parameterJson);

                        string tableName = RECORD_COLLECTION_PREFIX + entity.Name;

                        DbRepository.CreateTable(tableName);
                        foreach (var field in entity.Fields)
                        {
                            bool isPrimaryKey = field.Name.ToLowerInvariant() == "id";
                            FieldType fieldType = field.GetFieldType();
                            DbRepository.CreateColumn(tableName, field.Name, fieldType, isPrimaryKey, field.GetDefaultValue(), !field.Required);
                        }

                        bool result = DbRepository.InsertRecord("entities", parameters);

                        if (!result)
                            throw new Exception("Entity record was not added!");

                        if (entity.Id != SystemIds.UserEntityId)
                        {
                            DbEntity userEntity = Read(SystemIds.UserEntityId);

                            DbRelationRepository relRep = new DbRelationRepository();

                            string createdByRelationName = $"user_{entity.Name}_created_by";
                            string modifiedByRelationName = $"user_{entity.Name}_modified_by";

                            Guid createdByRelationId = Guid.NewGuid();
                            if (sysldDictionary != null && sysldDictionary.ContainsKey(createdByRelationName))
                                createdByRelationId = sysldDictionary[createdByRelationName];

                            Guid modifiedByRelationId = Guid.NewGuid();
                            if (sysldDictionary != null && sysldDictionary.ContainsKey(modifiedByRelationName))
                                modifiedByRelationId = sysldDictionary[modifiedByRelationName];

                            List<DbEntityRelation> relationList = relRep.Read();
                            DbEntityRelation tempRel = relationList.FirstOrDefault(r => r.Name == createdByRelationName);
                            if (tempRel != null)
                            {
                                createdByRelationId = tempRel.Id;
                                relRep.Delete(createdByRelationId);
                            }
                            tempRel = relationList.FirstOrDefault(r => r.Name == modifiedByRelationName);
                            if (tempRel != null)
                            {
                                modifiedByRelationId = tempRel.Id;
                                relRep.Delete(modifiedByRelationId);
                            }

                            DbEntityRelation createdByRelation = new DbEntityRelation();
                            createdByRelation.Id = createdByRelationId;
                            createdByRelation.Name = createdByRelationName;
                            createdByRelation.Label = $"user<-[1]:[m]->{entity.Name}.created_by";
                            createdByRelation.RelationType = EntityRelationType.OneToMany;
                            createdByRelation.OriginEntityId = SystemIds.UserEntityId;
                            createdByRelation.OriginFieldId = userEntity.Fields.Single(f => f.Name == "id").Id;
                            createdByRelation.TargetEntityId = entity.Id;
                            createdByRelation.TargetFieldId = entity.Fields.Single(f => f.Name == "created_by").Id;
                            {
                                bool res = relRep.Create(createdByRelation);
                                if (!res)
                                    throw new Exception("Creation of relation between User and Area entities failed!");
                            }

                            DbEntityRelation modifiedByRelation = new DbEntityRelation();
                            modifiedByRelation.Id = modifiedByRelationId;
                            modifiedByRelation.Name = modifiedByRelationName;
                            modifiedByRelation.Label = "user<-[1]:[m]->area.last_modified_by";
                            modifiedByRelation.RelationType = EntityRelationType.OneToMany;
                            modifiedByRelation.OriginEntityId = SystemIds.UserEntityId;
                            modifiedByRelation.OriginFieldId = userEntity.Fields.Single(f => f.Name == "id").Id;
                            modifiedByRelation.TargetEntityId = entity.Id;
                            modifiedByRelation.TargetFieldId = entity.Fields.Single(f => f.Name == "last_modified_by").Id;
                            {
                                bool res = relRep.Create(modifiedByRelation);
                                if (!res)
                                    throw new Exception($"Creation of relation between User and {entity.Name} entities failed!");
                            }
                        }
                        con.CommitTransaction();

                        return result;
                    }
                    catch (Exception)
                    {
                        con.RollbackTransaction();
                    }
                }
                return false;
            }
            finally
            {
                Cache.Clear();
            }
        }