/// <summary>
        /// Returns the current domain model as "insert into" from another database with the same structure.
        /// The tables will be unordered (add your constraints afterwards) and remember to tweak each table as needed
        /// </summary>
        internal static string GetTransferScript <T>(string otherDatabaseName, params ExpressionProperty[] toSkip)
        {
            var tables           = new StringBuilder();
            var manyToManyTables = new StringBuilder();

            foreach (var type in DwarfHelper.GetValidTypes <T>())
            {
                var typeProps = (DwarfHelper.GetDBProperties(type).Union(DwarfHelper.GetGemListProperties(type))).Where(x => !toSkip.Contains(x)).Flatten(x => "[" + (x.PropertyType.Implements <IDwarf>() ? x.Name + "Id" : x.Name) + "], ");
                typeProps = typeProps.TruncateEnd(2);

                tables.AppendLine(string.Format("INSERT INTO [{0}] ({1}) (SELECT {1} from [{2}].dbo.[{0}])", type.Name, typeProps, otherDatabaseName));

                foreach (var ep in DwarfHelper.GetManyToManyProperties(type))
                {
                    var tableName = ManyToManyAttribute.GetTableName(type, ep.ContainedProperty);

                    if (manyToManyTables.ToString().Contains(tableName))
                    {
                        continue;
                    }

                    var m2mProps = "[" + type.Name + "Id], [" + ep.PropertyType.GetGenericArguments()[0].Name + "Id]";

                    manyToManyTables.AppendLine(string.Format("INSERT INTO [{0}] ({1}) (SELECT {1} from [{2}].dbo.[{0}])", tableName, m2mProps, otherDatabaseName));
                }
            }

            return(tables.ToString() + manyToManyTables);
        }
Esempio n. 2
0
        public void TestSignedLEB128(long value)
        {
            var stream = new MemoryStream();

            {
                // check positive
                stream.WriteILEB128(value);
                Assert.AreEqual((uint)stream.Position, DwarfHelper.SizeOfILEB128(value));

                stream.Position = 0;
                var readbackValue = stream.ReadSignedLEB128();
                Assert.AreEqual(value, readbackValue);
            }

            {
                stream.Position = 0;
                // Check negative
                value = -value;
                stream.WriteILEB128(value);
                Assert.AreEqual((uint)stream.Position, DwarfHelper.SizeOfILEB128(value));

                stream.Position = 0;
                var readbackValue = stream.ReadSignedLEB128();
                Assert.AreEqual(value, readbackValue);
            }
        }
 /// <summary>
 /// Creates unique constraints for the supplied type
 /// </summary>
 internal static void CreateUniqueConstraint <T>(StringBuilder constraints, Type type)
 {
     foreach (var uniqueGroupName in DwarfHelper.GetUniqueGroupNames <T>(type))
     {
         CreateUniqueConstraint <T>(constraints, type, uniqueGroupName);
     }
 }
Esempio n. 4
0
        /// <summary>
        /// Builds and executes insert statement
        /// </summary>
        public virtual void Insert <T, TY>(Dwarf <TY> dwarf, Guid?customId = null) where TY : Dwarf <TY>, new()
        {
            var type = DbContextHelper <T> .ClearCacheForType(DwarfHelper.DeProxyfy(dwarf));

            dwarf.Id = customId ?? Guid.NewGuid();

            ExecuteNonQuery <T, TY>(new QueryBuilder <T>().InsertInto(type).Values(dwarf));

            dwarf.IsSaved = true;
        }
        /// <summary>
        /// Creates unique constraints for the supplied type and group name
        /// </summary>
        internal static void CreateUniqueConstraint <T>(StringBuilder constraints, Type type, string uniqueGroupName)
        {
            var constraintName = "UQ_" + type.Name + "_" + uniqueGroupName;

            var columns = DwarfHelper.GetUniqueGroupProperties <T>(type, uniqueGroupName).Select(x => QueryBuilder.GetColumnName(x.ContainedProperty)).
                          Aggregate(String.Empty, (s, x) => s + ", [" + x + "]").Remove(0, 2);

            var alterTable = "ALTER TABLE [" + type.Name + "] ADD CONSTRAINT [" + constraintName + "] UNIQUE (" + columns + ")";

            constraints.AppendLine(alterTable);
        }
Esempio n. 6
0
        /// <summary>
        /// Builds and executes an update statement
        /// </summary>
        public virtual void Update <T>(Dwarf <T> dwarf, IEnumerable <ExpressionProperty> properties) where T : Dwarf <T>, new()
        {
            var type = DbContextHelper <T> .ClearCacheForType(DwarfHelper.DeProxyfy(dwarf));

            var command = new QueryBuilder <T>()
                          .Update(type)
                          .Set(dwarf, properties)
                          .Where(dwarf, Cfg.PKProperties[type]);

            ExecuteNonQuery <T>(command);
        }
        /// <summary>
        /// Generates create table commands for the supplied type
        /// </summary>
        internal static void CreateTable <T>(StringBuilder tables, Type type, StringBuilder constraints, StringBuilder manyToManyTables)
        {
            tables.AppendLine("CREATE TABLE [" + type.Name + "] ( ");

            foreach (var pi in DwarfHelper.GetDBProperties(type))
            {
                tables.AppendLine(TypeToColumnName(pi) + " " + TypeToColumnConstruction(type, pi.ContainedProperty));
            }

            foreach (var pi in DwarfHelper.GetGemListProperties(type))
            {
                tables.AppendLine(TypeToColumnName(pi) + " " + TypeToColumnConstruction(type, pi.ContainedProperty));
            }

            foreach (var manyToManyProperty in DwarfHelper.GetManyToManyProperties(type))
            {
                CreateManyToManyTable(type, manyToManyProperty, manyToManyTables, constraints);
            }

            var keys = String.Empty;

            foreach (var propertyInfo in DwarfHelper.GetPKProperties(type))
            {
                keys += TypeToColumnName(propertyInfo) + ", ";
            }

            if (!string.IsNullOrEmpty(keys))
            {
                keys = keys.TruncateEnd(2);

                keys = "CONSTRAINT [PK_" + type.Name + "] PRIMARY KEY (" + keys + ")";

                tables.AppendLine(keys);
            }

            foreach (var pi in DwarfHelper.GetFKProperties <T>(type))
            {
                var constraintName = "FK_" + type.Name + "_" + pi.Name;

                var alterTable = "ALTER TABLE [" + type.Name + "] ADD CONSTRAINT [" + constraintName + "Id] FOREIGN KEY (" +
                                 pi.Name + "Id) REFERENCES [" + pi.PropertyType.Name + "] (Id)";

                if (!DwarfPropertyAttribute.GetAttribute(pi.ContainedProperty).DisableDeleteCascade)
                {
                    alterTable += " ON DELETE CASCADE ";
                }

                constraints.AppendLine(alterTable);
            }
            CreateUniqueConstraint <T>(constraints, type);

            tables.AppendLine(") ");
            tables.AppendLine();
        }
Esempio n. 8
0
        /// <summary>
        /// Builds and executes a delete statement
        /// </summary>
        public virtual void Delete <T>(Dwarf <T> dwarf) where T : Dwarf <T>, new()
        {
            var type = DbContextHelper <T> .ClearCacheForType(DwarfHelper.DeProxyfy(dwarf));

            var command = new QueryBuilder <T>()
                          .DeleteFrom <T>()
                          .Where(dwarf, Cfg.PKProperties[type]);

            ExecuteNonQuery <T>(command);

            dwarf.IsSaved = false;
        }
        /// <summary>
        /// Converts and returns the current domain model as create scripts (incl keys)
        /// </summary>
        internal static string GetCreateScript <T>(string connectionString = null, bool hideOptionalStuff = false)
        {
            var tables           = new StringBuilder();
            var constraints      = new StringBuilder();
            var manyToManyTables = new StringBuilder();

            foreach (var type in DwarfHelper.GetValidTypes <T>())
            {
                CreateTable <T>(tables, type, constraints, manyToManyTables);
            }

            return(tables.ToString() + manyToManyTables + constraints);
        }
Esempio n. 10
0
        public void TestLEB128(ulong value)
        {
            var stream = new MemoryStream();

            stream.WriteULEB128(value);

            Assert.AreEqual((uint)stream.Position, DwarfHelper.SizeOfULEB128(value));

            stream.Position = 0;
            var readbackValue = stream.ReadULEB128();

            Assert.AreEqual(value, readbackValue);
        }
        private static string GetDropConstraintsScript <T>()
        {
            var constraints = new StringBuilder();

            foreach (var type in DwarfHelper.GetValidTypes <T>())
            {
                foreach (var pi in DwarfHelper.GetFKProperties <T>(type))
                {
                    var fk = "FK_" + type.Name + "_" + pi.Name + "Id";
                    constraints.AppendLine("IF EXISTS (SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N'[" + fk + "]') AND PARENT_OBJECT_ID = OBJECT_ID('[" + type.Name + "]')) ALTER TABLE [" + type.Name + "] DROP CONSTRAINT [" + fk + "]");
                }
            }

            return(constraints.ToString());
        }
        private static IEnumerable <string> GetCurrentManyToManyTables(IEnumerable <Type> allTypes)
        {
            foreach (var type in allTypes)
            {
                foreach (var pi in DwarfHelper.GetManyToManyProperties(type))
                {
                    var value = ManyToManyAttribute.GetTableName(type, pi.ContainedProperty);

                    if (!string.IsNullOrEmpty(value))
                    {
                        yield return(value);
                    }
                }
            }
        }
Esempio n. 13
0
        public TY Select <T, TY>(params WhereCondition <TY>[] conditions) where TY : Dwarf <TY>, new()
        {
            if (!typeof(TY).Implements <ICompositeId>())
            {
                throw new InvalidOperationException("Use Select for non-CompositeId types");
            }

            var command = new QueryBuilder()
                          .Select <TY>()
                          .From <TY>()
                          .Where(conditions).ToQuery();

            var uniqueKey = DwarfHelper.GetUniqueKeyForCompositeId(conditions);

            TY result = null;

            if (!typeof(TY).Implements <ICacheless>() && CacheManager.TryGetCache(uniqueKey, out result))
            {
                return(result);
            }

            var sdr = (SqlDataReader)ExecuteReader <T, TY>(command);

            try
            {
                result = sdr.Read() ? TupleToObject <TY>(sdr) : null;
            }
            catch (Exception e)
            {
                DwarfContext <T> .GetConfiguration().ErrorLogService.Logg(e);
            }
            finally
            {
                sdr.Close();
            }

            if (typeof(TY).Implements <ICacheless>())
            {
                return(result);
            }

            return(result != null
                       ? CacheManager.SetCache(DwarfHelper.GetUniqueKeyForCompositeId(result), result)
                       : CacheManager.SetCache(DwarfHelper.GetUniqueKeyForCompositeId(conditions), (TY)null));
        }
        private static string GetDropTablesScript <T>()
        {
            var tables           = new StringBuilder();
            var manyToManyTables = new StringBuilder();

            foreach (var type in DwarfHelper.GetValidTypes <T>())
            {
                foreach (var manyToManyProperty in DwarfHelper.GetManyToManyProperties(type))
                {
                    var tableName = ManyToManyAttribute.GetTableName(type, manyToManyProperty.ContainedProperty);

                    if (!manyToManyTables.ToString().Contains("DROP TABLE [" + tableName + "]"))
                    {
                        manyToManyTables.AppendLine("IF EXISTS (SELECT * FROM dbo.sysobjects WHERE Id = OBJECT_ID(N'[" + tableName + "]') AND OBJECTPROPERTY(Id, N'IsUserTable') = 1) DROP Table [" + tableName + "]");
                    }
                }
                if (type.Implements <IDwarf>() && !type.IsAbstract)
                {
                    tables.AppendLine("IF EXISTS (SELECT * FROM dbo.sysobjects WHERE Id = OBJECT_ID(N'[" + type.Name + "]') AND OBJECTPROPERTY(Id, N'IsUserTable') = 1) DROP Table [" + type.Name + "]");
                }
            }

            return(manyToManyTables.ToString() + tables);
        }
Esempio n. 15
0
        /// <summary>
        /// See base
        /// </summary>
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
            {
                return(null);
            }

            if (reader.TokenType == JsonToken.String)
            {
                var val = reader.Value;

                if (val != null && !string.IsNullOrEmpty(val.ToString()))
                {
                    return(DwarfHelper.Load(objectType, Guid.Parse(val.ToString())));
                }

                return(null);
            }

            var jObject = JObject.Load(reader);

            object obj = null;

            if (jObject.Property("id") != null)
            {
                var id = jObject.Property("id").Value.ToObject <Guid?>();

                if (id.HasValue)
                {
                    obj = DwarfHelper.Load(objectType, id.Value);
                }

                if (obj == null)
                {
                    if (HttpContext.Current.Items.Contains(id.Value.ToString()))
                    {
                        obj = HttpContext.Current.Items[id.Value.ToString()];
                    }
                    else
                    {
                        obj = DwarfHelper.CreateInstance(objectType);
                        ((IDwarf)obj).Id = id;
                        HttpContext.Current.Items[id.Value.ToString()] = obj;
                    }
                }
            }
            else
            {
                obj = DwarfHelper.CreateInstance(objectType);
            }

            if (obj == null)
            {
                throw new JsonSerializationException("No object created.");
            }

            var writer = new StringWriter();

            serializer.Serialize(writer, jObject);

            using (var newReader = new JsonTextReader(new StringReader(writer.ToString())))
            {
                newReader.Culture              = reader.Culture;
                newReader.DateParseHandling    = reader.DateParseHandling;
                newReader.DateTimeZoneHandling = reader.DateTimeZoneHandling;
                newReader.FloatParseHandling   = reader.FloatParseHandling;
                serializer.Populate(newReader, obj);
            }

            return(obj);
        }
Esempio n. 16
0
        /// <summary>
        /// Bulk inserts the supplied objects using SqlBulkCopy
        /// </summary>
        public virtual void BulkInsert <T>(IEnumerable <T> objects) where T : Dwarf <T>, new()
        {
            var list = objects.ToList();

            if (!list.Any())
            {
                return;
            }

            var properties = DwarfHelper.GetDBProperties <T>().ToList();

            var dt = new DataTable();

            foreach (var pi in properties)
            {
                if (pi.PropertyType.Implements <IDwarf>())
                {
                    dt.Columns.Add(pi.Name + "Id", typeof(Guid));
                }
                else if (pi.PropertyType.IsEnum())
                {
                    dt.Columns.Add(pi.Name, typeof(string));
                }
                else
                {
                    dt.Columns.Add(pi.Name, Nullable.GetUnderlyingType(pi.PropertyType) ?? pi.PropertyType);
                }
            }

            Parallel.ForEach(list, obj =>
            {
                if (obj.IsSaved)
                {
                    return;
                }

                obj.Id = obj.Id.HasValue ? obj.Id.Value : Guid.NewGuid();

                var row = new object[properties.Count];

                for (var i = 0; i < properties.Count; i++)
                {
                    var value = properties[i].GetValue(obj);

                    if (properties[i].PropertyType.Implements <IDwarf>())
                    {
                        if (value != null)
                        {
                            row[i] = ((IDwarf)value).Id;
                        }
                        else
                        {
                            row[i] = DBNull.Value;
                        }
                    }
                    else
                    {
                        row[i] = value ?? DBNull.Value;
                    }
                }

                obj.IsSaved = true;

                lock (dt.Rows.SyncRoot)
                    dt.Rows.Add(row);
            });

            var con = (SqlConnection)DbContextHelper <T> .OpenConnection();

            var copy = new SqlBulkCopy(con, SqlBulkCopyOptions.Default, (SqlTransaction)DbContextHelper <T> .Transaction)
            {
                DestinationTableName = typeof(T).Name,
                BulkCopyTimeout      = 10000,
                BatchSize            = 2500,
            };

            foreach (DataColumn column in dt.Columns)
            {
                copy.ColumnMappings.Add(column.ColumnName, column.ColumnName);
            }

            copy.WriteToServer(dt);

            if (con != DbContextHelper <T> .Connection)
            {
                con.Dispose();
            }

            objects.ForEachX(x => x.IsSaved = true);
        }
        /// <summary>
        /// Analyses the current domain model and database and generates update scripts in an attempt to synchronize them.
        /// Note that a few places might need manual coding, such as when columns become not nullable, when target types changes, etc. Look for "Warning!!"
        /// in the generated code
        /// </summary>
        internal static string GetUpdateScript <T>(Assembly assembly = null)
        {
            var database = Cfg.Databases[assembly ?? typeof(T).Assembly];

            var dropPKConstraints   = new StringBuilder();
            var dropFKConstraints   = new StringBuilder();
            var dropColumns         = new StringBuilder();
            var dropTables          = new StringBuilder();
            var addTables           = new StringBuilder();
            var addManyToManyTables = new StringBuilder();
            var addColumns          = new StringBuilder();
            var addConstraints      = new StringBuilder();

            var allCurrentDomainTypes = DwarfHelper.GetValidTypes <T>().ToList();

            var currentManyToManyTables = GetCurrentManyToManyTables(allCurrentDomainTypes).Distinct().ToList();

            var existingDatabaseTables = DwarfContext <T> .GetConfiguration().Database.ExecuteQuery("SELECT t.name FROM sys.tables t JOIN sys.schemas s ON s.schema_id = t.schema_id ").Select(x => x.name).ToList();

            foreach (var existingTable in existingDatabaseTables.ToArray())
            {
                if (!allCurrentDomainTypes.Select(x => x.Name).Any(x => x.Equals(existingTable)) && !currentManyToManyTables.Any(x => x.Equals(existingTable)))
                {
                    DropDeadTableConstraints <T>(dropPKConstraints, dropFKConstraints, existingTable);
                    dropTables.AppendLine("IF EXISTS (SELECT * FROM dbo.sysobjects WHERE Id = OBJECT_ID(N'[" + existingTable + "]') AND OBJECTPROPERTY(Id, N'IsUserTable') = 1) DROP Table [" + existingTable + "] ");
                    existingDatabaseTables.Remove(existingTable);

                    var constraints = DwarfContext <T> .GetDatabase().ExecuteCustomQuery <T>("select CONSTRAINT_NAME from INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = '" + existingTable + "' ");

                    foreach (var constraint in constraints)
                    {
                        AddDropConstraint(dropPKConstraints, dropFKConstraints, "IF EXISTS (SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N'[" + constraint.CONSTRAINT_NAME + "]') AND PARENT_OBJECT_ID = OBJECT_ID('[" + existingTable + "]')) ALTER TABLE [" + existingTable + "] DROP CONSTRAINT [" + constraint.CONSTRAINT_NAME + "]");
                    }
                }
            }

            foreach (var type in allCurrentDomainTypes)
            {
                if (!existingDatabaseTables.Contains(type.Name))
                {
                    CreateTable <T>(addTables, type, addConstraints, addManyToManyTables);
                }

                foreach (var pi in DwarfHelper.GetManyToManyProperties(type))
                {
                    if (!existingDatabaseTables.Contains(ManyToManyAttribute.GetTableName(type, pi.ContainedProperty)))
                    {
                        CreateManyToManyTable(type, pi, addManyToManyTables, addConstraints);
                    }
                }
            }

            foreach (var existingTable in existingDatabaseTables)
            {
                if (!allCurrentDomainTypes.Any(x => x.Name.Equals(existingTable)))
                {
                    continue;
                }

                var existingColumns = (List <dynamic>) DwarfContext <T> .GetDatabase().ExecuteCustomQuery <T>("SELECT c.name as name1, t.name as name2, c.max_length, c.is_nullable FROM sys.columns c inner join sys.types t on t.user_type_id = c.user_type_id WHERE object_id = OBJECT_ID('dbo." + existingTable + "') ");

                var type  = allCurrentDomainTypes.First(x => x.Name.Equals(existingTable));
                var props = DwarfHelper.GetGemListProperties(type).Union(DwarfHelper.GetDBProperties(type)).ToList();

                foreach (var existingColumn in existingColumns)
                {
                    string columnName = existingColumn.name1.ToString();

                    var pi = props.FirstOrDefault(x => x.Name.Equals(existingColumn.name2.ToString().Equals("uniqueidentifier") && !x.Name.Equals("Id") ? (columnName.EndsWith("Id") ? columnName.TruncateEnd(2) : columnName) : columnName));

                    if (pi == null)
                    {
                        dropColumns.AppendLine("IF EXISTS (SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[" + existingTable + "]') AND Name = '" + columnName + "') ALTER TABLE dbo.[" + existingTable + "] DROP COLUMN " + columnName);

                        if (existingColumn.name2.Equals("uniqueidentifier"))
                        {
                            var fkName = "FK_" + existingTable + "_" + columnName;
                            AddDropConstraint(dropPKConstraints, dropFKConstraints, "IF EXISTS (SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N'[" + fkName + "]') AND PARENT_OBJECT_ID = OBJECT_ID('[" + existingTable + "]')) ALTER TABLE [" + existingTable + "] DROP CONSTRAINT [" + fkName + "]");
                        }
                    }
                }

                foreach (var pi in props)
                {
                    if (DwarfPropertyAttribute.GetAttribute(pi.ContainedProperty) == null && !pi.PropertyType.Implements <IGemList>())
                    {
                        continue;
                    }

                    var existingColumn = existingColumns.FirstOrDefault(x => (pi.PropertyType.Implements <IDwarf>() ? pi.Name + "Id" : pi.Name).Equals(x.name1));

                    if (existingColumn != null)
                    {
                        var typeChanged     = !existingColumn.name2.Equals(TypeToColumnType(pi.ContainedProperty));
                        var lengthChanged   = pi.PropertyType == typeof(string) && (existingColumn.name2.ToString().Equals(DwarfPropertyAttribute.GetAttribute(pi.ContainedProperty).UseMaxLength ? "-1" : "255"));
                        var nullableChanged = (bool.Parse(existingColumn.is_nullable.ToString()) != IsColumnNullable(type, pi.ContainedProperty));

                        if (typeChanged | nullableChanged | lengthChanged)
                        {
                            addColumns.AppendLine("-- WARNING! TYPE CONVERSION MIGHT FAIL!!! ");
                            addColumns.AppendLine("ALTER TABLE [" + type.Name + "] ALTER COLUMN " + TypeToColumnName(pi) + " " + TypeToColumnConstruction(type, pi.ContainedProperty, true).TruncateEnd(2));
                            addColumns.AppendLine("GO ");
                        }

                        if (pi.PropertyType.Implements <IDwarf>())
                        {
                            var fkName           = "FK_" + type.Name + "_" + pi.Name + "Id";
                            var constraintExists = DwarfContext <T> .GetDatabase().ExecuteCustomQuery <T>("SELECT t.name FROM sys.objects obj inner join sys.foreign_key_columns fk on obj.object_id = fk.constraint_object_id inner join sys.columns c on fk.referenced_object_id = c.object_id and fk.referenced_column_id = c.column_id inner join sys.tables t on t.object_id = c.object_id inner join sys.tables t2 on fk.parent_object_id = t2.object_id WHERE obj.type = 'F' and t2.name = '" + type.Name + "' and obj.name = '" + fkName + "' and t.name = '" + pi.PropertyType.Name + "'");

                            if (!constraintExists.Any())
                            {
                                dropColumns.AppendLine("IF EXISTS (SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[" + existingTable + "]') AND Name = '" + existingColumn.name1 + "') ALTER TABLE dbo.[" + existingTable + "] DROP COLUMN " + existingColumn.name1);

                                AddDropConstraint(dropPKConstraints, dropFKConstraints, "IF EXISTS (SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N'[" + fkName + "]') AND PARENT_OBJECT_ID = OBJECT_ID('[" + existingTable + "]')) ALTER TABLE [" + existingTable + "] DROP CONSTRAINT [" + fkName + "]");

                                if (IsColumnNullable(type, pi.ContainedProperty))
                                {
                                    addColumns.AppendLine("ALTER TABLE [" + type.Name + "] ADD " + TypeToColumnName(pi) + " " + TypeToColumnConstruction(type, pi.ContainedProperty).TruncateEnd(2));
                                    addColumns.AppendLine("GO ");
                                }
                                else
                                {
                                    object value = null;

                                    try { value = Activator.CreateInstance(pi.PropertyType); }
                                    catch { }

                                    addColumns.AppendLine("GO ");
                                    addColumns.AppendLine("ALTER TABLE [" + type.Name + "] ADD " + TypeToColumnName(pi) + " " + TypeToColumnType(pi.ContainedProperty));
                                    addColumns.AppendLine("GO ");
                                    addColumns.AppendLine("-- WARNING! Value is probably wrong. Correct before you execute! ");
                                    addColumns.AppendLine("UPDATE [" + type.Name + "] SET " + TypeToColumnName(pi) + " = " + database.ValueToSqlString(value) + " ");
                                    addColumns.AppendLine("GO ");
                                    addColumns.AppendLine("ALTER TABLE [" + type.Name + "] ALTER COLUMN " + TypeToColumnName(pi) + " " + TypeToColumnConstruction(type, pi.ContainedProperty, true).TruncateEnd(2));
                                    addColumns.AppendLine("GO ");
                                }

                                var alterTable = "ALTER TABLE [" + type.Name + "] ADD CONSTRAINT [" + fkName + "] FOREIGN KEY (" + pi.Name + "Id) REFERENCES [" + pi.PropertyType.Name + "] (Id)";

                                if (!DwarfPropertyAttribute.GetAttribute(pi.ContainedProperty).DisableDeleteCascade)
                                {
                                    alterTable += " ON DELETE CASCADE ";
                                }

                                addConstraints.AppendLine(alterTable);
                                addConstraints.AppendLine("GO ");
                            }
                        }
                    }
                    else
                    {
                        if (IsColumnNullable(type, pi.ContainedProperty))
                        {
                            addColumns.AppendLine("ALTER TABLE [" + type.Name + "] ADD " + TypeToColumnName(pi) + " " + TypeToColumnConstruction(type, pi.ContainedProperty).TruncateEnd(2));
                            addColumns.AppendLine("GO ");
                        }
                        else
                        {
                            object value = null;

                            try { value = Activator.CreateInstance(pi.PropertyType); }
                            catch { }

                            addColumns.AppendLine("GO ");
                            addColumns.AppendLine("ALTER TABLE [" + type.Name + "] ADD " + TypeToColumnName(pi) + " " + " " + TypeToColumnConstruction(type, pi.ContainedProperty).TruncateEnd(2).Replace("NOT NULL", string.Empty));
                            addColumns.AppendLine("GO ");
                            addColumns.AppendLine("-- WARNING! Value is probably wrong. Correct before you execute! ");
                            addColumns.AppendLine("UPDATE [" + type.Name + "] SET " + TypeToColumnName(pi) + " = " + database.ValueToSqlString(value) + " ");
                            addColumns.AppendLine("GO ");
                            addColumns.AppendLine("ALTER TABLE [" + type.Name + "] ALTER COLUMN " + TypeToColumnName(pi) + " " + TypeToColumnConstruction(type, pi.ContainedProperty, true).TruncateEnd(2));
                            addColumns.AppendLine("GO ");
                        }

                        if (pi.PropertyType.Implements <IDwarf>())
                        {
                            var constraintName = "FK_" + type.Name + "_" + pi.Name;

                            var alterTable = "ALTER TABLE [" + type.Name + "] ADD CONSTRAINT [" + constraintName + "Id] FOREIGN KEY (" + pi.Name + "Id) REFERENCES [" + pi.PropertyType.Name + "] (Id)";

                            if (!DwarfPropertyAttribute.GetAttribute(pi.ContainedProperty).DisableDeleteCascade)
                            {
                                alterTable += " ON DELETE CASCADE ";
                            }

                            addConstraints.AppendLine(alterTable);
                            addColumns.AppendLine("GO ");
                        }
                    }
                }
            }

            foreach (var existingTable in existingDatabaseTables)
            {
                var uqConstraints = ((List <dynamic>)DwarfContext <T> .GetDatabase().ExecuteCustomQuery <T>("SELECT obj.name FROM sys.objects obj inner join sys.tables t on obj.parent_object_id = t.object_id WHERE obj.type = 'UQ' and t.name = '" + existingTable + "'")).Select(x => x.name);

                foreach (var uqConstraint in uqConstraints)
                {
                    var uqParts = uqConstraint.Split('_');

                    var type = allCurrentDomainTypes.FirstOrDefault(x => x.Name.Equals(uqParts[1]));

                    if (type != null)
                    {
                        var columns = (List <dynamic>) DwarfContext <T> .GetDatabase().ExecuteCustomQuery <T>("select COLUMN_NAME from INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE where CONSTRAINT_NAME = '" + uqConstraint + "'");

                        //Not a unique combination, but a unique column (right?)
                        if (columns.Count == 1)
                        {
                            var pi = ColumnToProperty(type, columns.First().COLUMN_NAME);

                            if (pi != null)
                            {
                                var att = DwarfPropertyAttribute.GetAttribute(pi);

                                if (att != null && !att.IsUnique)
                                {
                                    AddDropConstraint(dropPKConstraints, dropFKConstraints, "IF EXISTS (SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N'[" + uqConstraint + "]') AND PARENT_OBJECT_ID = OBJECT_ID('[" + type.Name + "]')) ALTER TABLE [" + type.Name + "] DROP CONSTRAINT [" + uqConstraint + "]");
                                }
                            }
                        }
                        else
                        {
                            var uqProperties = (IEnumerable <ExpressionProperty>)DwarfHelper.GetUniqueGroupProperties <T>(type, uqParts[2]);

                            if (!uqProperties.Any())
                            {
                                AddDropConstraint(dropPKConstraints, dropFKConstraints, "IF EXISTS (SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N'[" + uqConstraint + "]') AND PARENT_OBJECT_ID = OBJECT_ID('[" + type.Name + "]')) ALTER TABLE [" + type.Name + "] DROP CONSTRAINT [" + uqConstraint + "]");
                            }
                            else
                            {
                                var difference = uqProperties.Select(x => x.Name).Except(columns.Select(x => x.COLUMN_NAME));

                                if (difference.Any())
                                {
                                    AddDropConstraint(dropPKConstraints, dropFKConstraints, "IF EXISTS (SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N'[" + uqConstraint + "]') AND PARENT_OBJECT_ID = OBJECT_ID('[" + type.Name + "]')) ALTER TABLE [" + type.Name + "] DROP CONSTRAINT [" + uqConstraint + "]");
                                    CreateUniqueConstraint <T>(addConstraints, type);
                                }
                            }
                        }
                    }
                }
            }

            foreach (var type in allCurrentDomainTypes)
            {
                foreach (var pi in DwarfHelper.GetUniqueDBProperties <T>(type))
                {
                    var piName = pi.Name + (pi.PropertyType.Implements <IDwarf>() ? "Id" : string.Empty);
                    var uqName = "UQ_" + type.Name + "_" + piName;

                    var columns = DwarfContext <T> .GetDatabase().ExecuteCustomQuery <T>("select COLUMN_NAME from INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE where CONSTRAINT_NAME = '" + uqName + "'");

                    if (columns.Count == 0 && !addColumns.ToString().Contains(uqName) && !addTables.ToString().Contains(uqName))
                    {
                        addConstraints.AppendLine("ALTER TABLE [" + type.Name + "] ADD CONSTRAINT [" + uqName + "] UNIQUE ([" + pi.Name + "]) ");
                        addConstraints.AppendLine("GO ");
                    }
                }

                foreach (var uniqueGroupName in DwarfHelper.GetUniqueGroupNames <T>(type))
                {
                    var pis = DwarfHelper.GetUniqueGroupProperties <T>(type, uniqueGroupName);

                    var columns = DwarfContext <T> .GetDatabase().ExecuteCustomQuery <T>("select COLUMN_NAME from INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE where CONSTRAINT_NAME = 'UQ_" + type.Name + "_" + uniqueGroupName + "'").Select(x => x.COLUMN_NAME).ToList();

                    if (columns.Any())
                    {
                        var differnce = pis.Select(x => x.Name).Except(columns);

                        if (differnce.Any())
                        {
                            AddDropConstraint(dropPKConstraints, dropFKConstraints, "IF EXISTS (SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N'[" + uniqueGroupName + "]') AND PARENT_OBJECT_ID = OBJECT_ID('[" + type.Name + "]')) ALTER TABLE [" + type.Name + "] DROP CONSTRAINT [" + uniqueGroupName + "]");
                            CreateUniqueConstraint <T>(addConstraints, type, uniqueGroupName);
                            addConstraints.AppendLine("GO ");
                        }
                    }
                    else
                    {
                        CreateUniqueConstraint <T>(addConstraints, type, uniqueGroupName);
                        addConstraints.AppendLine("GO ");
                    }
                }

                var uniqueColumns = DwarfContext <T> .GetDatabase().ExecuteCustomQuery <T>("select COLUMN_NAME, CONSTRAINT_NAME from INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE where CONSTRAINT_NAME like 'UQ_%' and CONSTRAINT_NAME like '%_' + COLUMN_NAME and TABLE_NAME = '" + type.Name + "' ");

                foreach (var uniqueColumn in uniqueColumns)
                {
                    var pi = ColumnToProperty(type, uniqueColumn.COLUMN_NAME.ToString());

                    if (pi == null)
                    {
                        AddDropConstraint(dropPKConstraints, dropFKConstraints, "IF EXISTS (SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N'[" + uniqueColumn.CONSTRAINT_NAME + "]') AND PARENT_OBJECT_ID = OBJECT_ID('[" + type.Name + "]')) ALTER TABLE [" + type.Name + "] DROP CONSTRAINT [" + uniqueColumn.CONSTRAINT_NAME + "]");
                        continue;
                    }

                    var att = DwarfPropertyAttribute.GetAttribute(pi);

                    if (att == null)
                    {
                        AddDropConstraint(dropPKConstraints, dropFKConstraints, "IF EXISTS (SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N'[" + uniqueColumn.CONSTRAINT_NAME + "]') AND PARENT_OBJECT_ID = OBJECT_ID('[" + type.Name + "]')) ALTER TABLE [" + type.Name + "] DROP CONSTRAINT [" + uniqueColumn.CONSTRAINT_NAME + "]");
                        continue;
                    }

                    if (!att.IsUnique)
                    {
                        AddDropConstraint(dropPKConstraints, dropFKConstraints, "IF EXISTS (SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N'[" + uniqueColumn.CONSTRAINT_NAME + "]') AND PARENT_OBJECT_ID = OBJECT_ID('[" + type.Name + "]')) ALTER TABLE [" + type.Name + "] DROP CONSTRAINT [" + uniqueColumn.CONSTRAINT_NAME + "]");
                    }
                }
            }


            var result = AppendSection(dropFKConstraints) +
                         AppendSection(dropPKConstraints) +
                         AppendSection(dropColumns) +
                         AppendSection(dropTables) +
                         AppendSection(addTables) +
                         AppendSection(addManyToManyTables) +
                         AppendSection(addColumns) +
                         AppendSection(addConstraints);


            if (!string.IsNullOrEmpty(result.Trim()))
            {
                return("--WARNING--\r\n" +
                       "--Use these scripts with caution as there's no guarantee that all model changes are --\r\n" +
                       "--reflected here nor that any previously persisted data will remain intact post execution. --\r\n" +
                       "\r\n" +
                       result);
            }
            return(string.Empty);
        }
Esempio n. 18
0
        /// <summary>
        /// Returns the ManyToMany table name for the supplied criteria
        /// </summary>
        public static string GetTableName <T>(Expression <Func <T, object> > exp)
        {
            var pi = PropertyHelper.GetProperty(DwarfHelper.DeProxyfy(typeof(T)), ReflectionHelper.GetPropertyName(exp));

            return(GetTableName(typeof(T), pi.ContainedProperty));
        }
Esempio n. 19
0
 protected override ulong GetLayoutHeaderSize()
 {
     // 3. debug_abbrev_offset (section offset)
     // 4. address_size (ubyte)
     return(DwarfHelper.SizeOfUInt(Is64BitEncoding) + 1);
 }
Esempio n. 20
0
        /// <summary>
        /// Converts an SqlDataReader row into an object of the type T
        /// </summary>
        protected T TupleToObject <T>(DbDataReader sdr) where T : Dwarf <T>, new()
        {
            var type = typeof(T);

            var obj = DwarfHelper.CreateInstance <T>();

            for (var i = 0; i < sdr.FieldCount; i++)
            {
                var propertyName  = sdr.GetName(i);
                var propertyValue = sdr.GetValue(i);

                var pi = PropertyHelper.GetProperty(type, propertyName) ?? PropertyHelper.GetProperty(type, propertyName.Replace("Id", string.Empty));

                if (pi == null)
                {
                    continue;
                }

                if (propertyValue is DBNull)
                {
                    propertyValue = pi.ContainedProperty.PropertyType == typeof(string) ? string.Empty : null;
                }
                else if (pi.PropertyType.Implements <IGem>())
                {
                    propertyValue = Cfg.LoadGem[pi.PropertyType](propertyValue.ToString());
                }
                else if (pi.PropertyType.IsEnum() && propertyValue != null)
                {
                    propertyValue = Enum.Parse(pi.PropertyType.GetTrueEnumType(), propertyValue.ToString());
                }
                else if (pi.PropertyType.Implements <Type>())
                {
                    propertyValue = typeof(T).Assembly.GetType(propertyValue.ToString());
                }
                else if (pi.PropertyType.Implements <IDwarf>())
                {
                    var att = DwarfPropertyAttribute.GetAttribute(pi.ContainedProperty);

                    if (att != null)
                    {
                        if (DwarfPropertyAttribute.IsFK(pi))
                        {
                            obj.SetOriginalValue(pi.Name, propertyValue);

                            if (att.EagerLoad)
                            {
                                var targetType = pi.PropertyType;

                                if (propertyValue != null)
                                {
                                    PropertyHelper.SetValue(obj, pi.Name, Cfg.LoadExpressions[targetType]((Guid)propertyValue));
                                }
                            }

                            continue;
                        }
                    }
                }

                if (pi.PropertyType == typeof(string) && propertyValue != null)
                {
                    propertyValue = propertyValue.ToString().Replace("\\r\\n", "\r\n");
                }

                PropertyHelper.SetValue(obj, pi.Name, propertyValue);
                obj.SetOriginalValue(pi.Name, propertyValue);
            }

            obj.IsSaved = true;

            return(obj);
        }