<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Signum.Engine;
using System.Data;
using Signum.Engine.Maps;
using Signum.Utilities;
using Signum.Entities;
using Signum.Engine.SchemaInfoTables;
using System.Text.RegularExpressions;
using Signum.Engine.Linq;
using Signum.Entities.Reflection;

namespace Signum.Engine
{
    public static class SchemaSynchronizer
    {
        public static SqlPreCommand SynchronizeSchemasScript(Replacements replacements)
        {
            HashSet<SchemaName> model = Schema.Current.GetDatabaseTables().Select(a => a.Name.Schema).ToHashSet();
            HashSet<SchemaName> database = new HashSet<SchemaName>();
            foreach (var db in model.Select(a => a.Database).Distinct())
	        {
                using (Administrator.OverrideDatabaseInViews(db))
                {
                    database.AddRange(
                     from s in Database.View<SysSchemas>()
                     select new SchemaName(db, s.name));
                }
	        }

            return Synchronizer.SynchronizeScript(
                model.ToDictionary(a => a),
                database.ToDictionary(a => a),
                (_, newSN) => SqlBuilder.CreateSchema(newSN),
                null,
                null, Spacing.Simple);
        }

        public static SqlPreCommand SynchronizeSystemDefaultConstraints(Replacements replacements)
        {
            var allConstraints = Schema.Current.DatabaseNames().SelectMany(db =>
            {
                using (Administrator.OverrideDatabaseInViews(db))
                {
                    return (from t in Database.View<SysTables>()
                            join s in Database.View<SysSchemas>() on t.schema_id equals s.schema_id
                            join c in Database.View<SysColumns>() on t.object_id equals c.object_id
                            join ctr in Database.View<SysDefaultConstraints>() on c.default_object_id equals ctr.object_id
                            where ctr.is_system_named
                            select new
                            {
                                table = new ObjectName(new SchemaName(db, s.name), t.name),
                                column = c.name,
                                constraint = ctr.name,
                                definition = ctr.definition,
                            }).ToList();
                }
            }).ToList();


            if (!allConstraints.Any())
                return null;

            return new SqlPreCommandSimple(
allConstraints.ToString(a => "-- because default constraint " + a.constraint + " in " + a.table.ToString() + "." + a.column, "\r\n") + @"
declare @sql nvarchar(max)
set @sql = ''
select @sql = @sql + 'ALTER TABLE [' + t.name + '] DROP CONSTRAINT [' + dc.name  + '];' 
from sys.default_constraints dc
join sys.tables t on dc.parent_object_id = t.object_id
exec sp_executesql @sql");
        } 

        public static SqlPreCommand SynchronizeTablesScript(Replacements replacements)
        {
            //Temproal HACK
            if (Database.View<SysIndexes>().Any(a => a.name.StartsWith("FIX")) && SafeConsole.Ask("Old index naming convention...rename first?"))
            {
                return Schema.Current.DatabaseNames().Select(db =>
                {<commit_msg>Synchronizer: Drop constraints from different databases<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Signum.Engine;
using System.Data;
using Signum.Engine.Maps;
using Signum.Utilities;
using Signum.Entities;
using Signum.Engine.SchemaInfoTables;
using System.Text.RegularExpressions;
using Signum.Engine.Linq;
using Signum.Entities.Reflection;

namespace Signum.Engine
{
    public static class SchemaSynchronizer
    {
        public static SqlPreCommand SynchronizeSchemasScript(Replacements replacements)
        {
            HashSet<SchemaName> model = Schema.Current.GetDatabaseTables().Select(a => a.Name.Schema).ToHashSet();
            HashSet<SchemaName> database = new HashSet<SchemaName>();
            foreach (var db in model.Select(a => a.Database).Distinct())
	        {
                using (Administrator.OverrideDatabaseInViews(db))
                {
                    database.AddRange(
                     from s in Database.View<SysSchemas>()
                     select new SchemaName(db, s.name));
                }
	        }

            return Synchronizer.SynchronizeScript(
                model.ToDictionary(a => a),
                database.ToDictionary(a => a),
                (_, newSN) => SqlBuilder.CreateSchema(newSN),
                null,
                null, Spacing.Simple);
        }

        public static SqlPreCommand SynchronizeSystemDefaultConstraints(Replacements replacements)
        {
            var allConstraints = Schema.Current.DatabaseNames().Select(db =>
            {
                using (Administrator.OverrideDatabaseInViews(db))
                {
                    var constaints = (from t in Database.View<SysTables>()
                                      join s in Database.View<SysSchemas>() on t.schema_id equals s.schema_id
                                      join c in Database.View<SysColumns>() on t.object_id equals c.object_id
                                      join ctr in Database.View<SysDefaultConstraints>() on c.default_object_id equals ctr.object_id
                                      where ctr.is_system_named
                                      select new
                                      {
                                          table = new ObjectName(new SchemaName(db, s.name), t.name),
                                          column = c.name,
                                          constraint = ctr.name,
                                          definition = ctr.definition,
                                      }).ToList();

                    if (!constaints.Any())
                        return null;

                    return new SqlPreCommandSimple(
                        constaints.ToString(a => "-- because default constraint " + a.constraint + " in " + a.table.ToString() + "." + a.column, "\r\n") + @"
                        declare @sql nvarchar(max)
                        set @sql = ''
                        select @sql = @sql + 'ALTER TABLE [' + t.name + '] DROP CONSTRAINT [' + dc.name  + '];' 
                        from {0}sys.default_constraints dc
                        join {0}sys.tables t on dc.parent_object_id = t.object_id
                        exec {0}dbo.sp_executesql @sql".Formato(db == null ? null : (db.ToString() + ".")));
                }
            }).ToList();

            return allConstraints.Combine(Spacing.Simple);
        } 

        public static SqlPreCommand SynchronizeTablesScript(Replacements replacements)
        {
            //Temproal HACK
            if (Database.View<SysIndexes>().Any(a => a.name.StartsWith("FIX")) && SafeConsole.Ask("Old index naming convention...rename first?"))
            {
                return Schema.Current.DatabaseNames().Select(db =>
                {
{'fraction_non_alphanumeric': 0.09634874357906428, 'fraction_numerical': 0.00041649312786339027, 'mean_word_length': 1.6101449275362318, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2967218', 'n_tokens_mistral': 1838, 'n_tokens_neox': 1746, 'n_words': 389}