Example #1
0
        internal static void GetAllColumnsAsCompositeKey(string tableName, XElement classXe, string outputNamespace)
        {
            if (UseUniqueClusteredIndexAsKey(tableName, classXe, outputNamespace))
            {
                return;
            }

            var          tbl              = tableName;
            var          compClassName    = Compose.CompKeyClassName(tbl, outputNamespace);
            const string compPropertyName = Globals.HbmXmlNames.ID;

            var compKeyXeNoPk  = XeFactory.CompositeIdNode(compPropertyName, compClassName);
            var allTblsColumns = Sorting.DbContainers.AllColumns.Data.Where(x => string.Equals(x.table_name, tbl, Sorting.C)).ToList();

            var composePk   = allTblsColumns.Where(x => x.is_nullable != null && x.is_nullable.Value == false).ToList();
            var simpleProps = allTblsColumns.Where(x => x.is_nullable == null || x.is_nullable.Value).ToList();

            if (composePk.Count <= 0)
            {
                throw new ItsDeadJim(
                          string.Format(
                              "The table named '{0}' has no PK, all of its columns are nullable and has no Unique Clustered Index " +
                              "to use as a substitute - add this to the 'DoNotReference' list and try again.",
                              tableName));
            }

            //max is 16 when using NHibernate.Tool.hbm2ddl.SchemaExport
            if (composePk.Count > 16)
            {
                composePk = composePk.Take(16).ToList();
                simpleProps.AddRange(composePk.Skip(16).Take(composePk.Count).ToList());
            }

            foreach (
                var simplePropXe in
                composePk.Select(columnData => GetSimplePropertyHbmXml(columnData, Globals.HbmXmlNames.KEY_PROPERTY)))
            {
                compKeyXeNoPk.Add(simplePropXe);
            }

            classXe.Add(compKeyXeNoPk);

            foreach (
                var simplePropXe in
                simpleProps.Select(columnData => GetSimplePropertyHbmXml(columnData, Globals.HbmXmlNames.PROPERTY)))
            {
                classXe.Add(simplePropXe);
            }
        }
Example #2
0
        internal static bool UseUniqueClusteredIndexAsKey(string tableName, XElement classXe, string outputNamespace)
        {
            var tbl = tableName;
            //a FK reference may be set to a table with no PK if the FK references a column that is non-nullable unique non-clustered index
            var uqIdxColumns =
                Sorting.DbContainers.UniqueClusteredIdxNotPks.Data.Where(
                    x => string.Equals(x.table_name, tbl, Sorting.C)).ToList();

            if (uqIdxColumns.Count <= 0)
            {
                return(false);
            }

            var allTblsColumns = Sorting.DbContainers.AllColumns.Data.Where(x => string.Equals(x.table_name, tbl, Sorting.C)).ToList();

            if (uqIdxColumns.Count == 1)
            {
                var pkId = uqIdxColumns.First();
                //need to look this up in AllColumns for other bits of info
                var acInfo =
                    Sorting.DbContainers.AllColumns.Data.First(
                        x => string.Equals(x.column_name, pkId.column_name, Sorting.C));
                pkId.CopyFrom(acInfo);

                GetSimpleId(pkId, classXe);
                foreach (
                    var simplePropXe in
                    allTblsColumns.Where(x => !string.Equals(x.column_name, pkId.column_name))
                    .Select(columnData => GetSimplePropertyHbmXml(columnData, Globals.HbmXmlNames.PROPERTY)))
                {
                    classXe.Add(simplePropXe);
                }
                return(true);
            }

            //although rare is is possiable to have a table with no PK and mutliple UqIdx - there is no way for the ORM to deal with this.
            var isIncompatiable = uqIdxColumns.Select(x => x.constraint_name).Distinct().ToList().Count > 1;

            if (isIncompatiable)
            {
                return(false);
            }

            var          compClassName    = Compose.CompKeyClassName(tbl, outputNamespace);
            const string compPropertyName = Globals.HbmXmlNames.ID;

            var compKeyXeNoPk = XeFactory.CompositeIdNode(compPropertyName, compClassName);

            //need to look this up in AllColumns for other bits of info
            foreach (var uqCol in uqIdxColumns)
            {
                var acInfo =
                    Sorting.DbContainers.AllColumns.Data.First(
                        x => string.Equals(x.column_name, uqCol.column_name, Sorting.C));
                uqCol.CopyFrom(acInfo);
            }

            foreach (
                var uqColData in
                uqIdxColumns.Select(columnData => GetSimplePropertyHbmXml(columnData, Globals.HbmXmlNames.KEY_PROPERTY)))
            {
                compKeyXeNoPk.Add(uqColData);
            }

            classXe.Add(compKeyXeNoPk);
            foreach (
                var simplePropXe in
                allTblsColumns.Where(x => !uqIdxColumns.Any(y => string.Equals(x.column_name, y.column_name)))
                .Select(columnData => GetSimplePropertyHbmXml(columnData, Globals.HbmXmlNames.PROPERTY)))
            {
                classXe.Add(simplePropXe);
            }

            return(true);
        }
Example #3
0
        protected static bool GetPk(string outputNamespace, string tbl, Dictionary <string, PkItem> hbmPk, XElement classXe)
        {
            //----PK
            var pkId         = hbmPk.ContainsKey(tbl) ? hbmPk[tbl].Id : null;
            var hasNoPkAtAll = !hbmPk.ContainsKey(tbl);

            if (pkId == null && !hasNoPkAtAll)
            {
                var          compClassName    = Compose.CompKeyClassName(tbl, outputNamespace);
                const string compPropertyName = Globals.HbmXmlNames.ID;
                var          compKeyXe        = XeFactory.CompositeIdNode(compPropertyName, compClassName);

                //key-many-to-one
                var hbmKeyManyToOne = hbmPk[tbl].KeyManyToOne ?? new Dictionary <string, List <ColumnMetadata> >();
                if (hbmKeyManyToOne.Count > 0)
                {
                    foreach (var keyname in hbmKeyManyToOne.Keys.Where(k => !Settings.DoNotReference.Contains(k)))
                    {
                        //need to iterate here on a per 'constraint_name', the json data-struct misses this
                        //eg a table, 4 columns; 2 are comp to another table's Pk and the other 2 are also a comp the SAME table's PK
                        var keyManytoOneColumns = new List <ColumnMetadata>();
                        if (!HbmKeys.GetKeyManyToOneColumns(tbl, ref keyManytoOneColumns))
                        {
                            continue;
                        }
                        foreach (var distinctColumn in keyManytoOneColumns.Distinct(new ConstraintNameComparer()))
                        {
                            var dKmtoCName = distinctColumn.constraint_name;
                            var keyMtoFullyQualTypeName = Compose.ClassName(keyname, outputNamespace);
                            var keyMtoNfTypeNameObj     = new NfTypeName(keyMtoFullyQualTypeName);
                            var keyMtoSimpleName        = keyMtoNfTypeNameObj.ClassName;

                            var keyMtoXe = XeFactory.KeyManyToOneNode(keyMtoSimpleName,
                                                                      keyMtoFullyQualTypeName);

                            var dKmtoColumnData = hbmKeyManyToOne[keyname].Where(
                                x =>
                                string.Equals(x.constraint_name, dKmtoCName, Sorting.C)).ToList();

                            if (dKmtoColumnData.Count <= 0)
                            {
                                continue;
                            }

                            foreach (var kmtoColumn in dKmtoColumnData)
                            {
                                kmtoColumn.CopyFrom(Sorting.GetFromAllColumnMetadata(kmtoColumn));
                                var fullColumnName = kmtoColumn.column_name;

                                //not having the naming pattern is exceptional
                                Compose.ValidSplit(fullColumnName, 3);

                                var keyMtoColumnXe =
                                    XeFactory.ColumnNode(NfString.ExtractLastWholeWord(fullColumnName, null),
                                                         kmtoColumn.ToJsonString());

                                keyMtoXe.Add(keyMtoColumnXe);
                            }

                            compKeyXe.Add(keyMtoXe);
                        } //end foreach distinct constraintname
                    }
                }         //end key-many-to-one

                var hbmKeyProperty = hbmPk[tbl].KeyProperty ?? new Dictionary <string, List <ColumnMetadata> >();

                //these would have been added as key-many-to-one, but thier underlying table has been excluded.
                foreach (var reduced in hbmKeyManyToOne.Where(k => Settings.DoNotReference.Contains(k.Key)))
                {
                    foreach (var redux in reduced.Value)
                    {
                        redux.CopyFrom(Sorting.GetFromAllColumnMetadata(redux));
                    }
                    //insure they got everything for being a value type

                    hbmKeyProperty.Add(reduced.Key, reduced.Value);
                }

                if (hbmKeyProperty.Count > 0)
                {
                    //Dictionary<string, List<ColumnMetadata>>
                    foreach (var keyName in hbmKeyProperty.Keys)
                    {
                        //SPECIAL NOTE: the original PS code seemed to imply that a key-property is always just one column...
                        var keyPropJsonData = hbmKeyProperty[keyName].FirstOrDefault();
                        if (keyPropJsonData == null)
                        {
                            continue;
                        }

                        keyPropJsonData.CopyFrom(Sorting.GetFromAllColumnMetadata(keyPropJsonData));
                        var keyPropPropertyName = Compose.PropertyName(keyPropJsonData.column_name);
                        var fullcolumnName      = keyPropJsonData.column_name;

                        Compose.ValidSplit(fullcolumnName, 3);

                        var keyPropDataType = Util.Lexicon.Mssql2HbmTypes[(keyPropJsonData.data_type)];
                        var keyPropColumn   = NfString.ExtractLastWholeWord(fullcolumnName, null);
                        var keyPropLen      = keyPropJsonData.string_length ?? Globals.MSSQL_MAX_VARCHAR;

                        if (string.Equals(keyPropDataType, Globals.HbmXmlNames.ANSI_STRING))
                        {
                            if (keyPropLen <= 0)
                            {
                                keyPropLen = Globals.MSSQL_MAX_VARCHAR;
                            }
                            var keyPropXe = XeFactory.KeyPropertyNode(keyPropPropertyName, keyPropColumn,
                                                                      keyPropDataType, keyPropLen.ToString(CultureInfo.InvariantCulture),
                                                                      keyPropJsonData.ToJsonString());
                            compKeyXe.Add(keyPropXe);
                        }
                        else
                        {
                            var keyPropXe = XeFactory.KeyPropertyNode(keyPropPropertyName, keyPropColumn,
                                                                      keyPropDataType, keyPropJsonData.ToJsonString());
                            compKeyXe.Add(keyPropXe);
                        }
                    }
                }
                classXe.Add(compKeyXe);
            }
            else if (pkId != null)
            {
                GetSimpleId(pkId, classXe);
            } //end PK
            return(hasNoPkAtAll);
        }