private static void ConvertIndexes(DataTable dt, ICollection<DatabaseIndex> indexes)
        {
            if (dt == null) return;
            //Npgsql
            if (dt.Columns.Count == 0) return;

            var indexKeyMap = new IndexKeyMap(dt);

            foreach (DataRowView row in dt.DefaultView)
            {
                string name = row[indexKeyMap.Key].ToString();
                if (string.IsNullOrEmpty(name)) continue; //all indexes should have a name
                string schema = !String.IsNullOrEmpty(indexKeyMap.SchemaKey) ? row[indexKeyMap.SchemaKey].ToString() : String.Empty;
                var tableName = row[indexKeyMap.TableKey].ToString();
                var c = indexes.FirstOrDefault(f => f.Name == name && f.SchemaOwner == schema && f.TableName.Equals(tableName, StringComparison.OrdinalIgnoreCase));
                if (c == null)
                {
                    c = new DatabaseIndex();
                    c.Name = name;
                    c.SchemaOwner = schema;
                    c.TableName = tableName;
                    if (indexKeyMap.Typekey != null)
                        c.IndexType = row[indexKeyMap.Typekey].ToString();
                    if (FindBoolean(row, indexKeyMap.UniqueKey, "UNIQUE"))
                    {
                        c.IsUnique = true;
                        c.IndexType = "UNIQUE";
                    }
                    if (FindBoolean(row, indexKeyMap.PrimaryKey, String.Empty))
                        c.IndexType = "PRIMARY"; //primary keys should be unique too
                    indexes.Add(c);
                }
                if (string.IsNullOrEmpty(indexKeyMap.ColumnKey)) continue;

                string colName = row[indexKeyMap.ColumnKey].ToString();
                if (string.IsNullOrEmpty(colName)) continue;
                var column = new DatabaseColumn();
                column.Name = colName;
                if (!string.IsNullOrEmpty(indexKeyMap.OrdinalKey))
                {
                    int ordinal = Convert.ToInt32(row[indexKeyMap.OrdinalKey], CultureInfo.CurrentCulture);
                    column.Ordinal = ordinal;
                }
                if (ContainsColumn(c.Columns, colName)) continue;
                c.Columns.Add(column);
                if (c.Columns.Count > 1 && column.Ordinal != 0)
                {
                    //the order of the datatable may be wrong
                    c.Columns.Sort((x, y) => x.Ordinal.CompareTo(y.Ordinal));
                }
            }
        }
        public void KeyMapForIndexSchemaTest()
        {
            //arrange
            var dataTable = new DataTable("Indexes") { Locale = CultureInfo.InvariantCulture };
            dataTable.Columns.Add("ConstraintCatalog", typeof(string));
            dataTable.Columns.Add("ConstraintSchema", typeof(string));
            dataTable.Columns.Add("ConstraintName", typeof(string));
            dataTable.Columns.Add("CatalogName", typeof(string));
            dataTable.Columns.Add("SchemaName", typeof(string));
            dataTable.Columns.Add("TableName", typeof(string));
            dataTable.Columns.Add("ConstraintType", typeof(string));

            //act
            var keymap = new IndexKeyMap(dataTable);

            //assert
            Assert.AreEqual("SchemaName", keymap.SchemaKey);
            Assert.AreEqual("TableName", keymap.TableKey);
            Assert.AreEqual("ConstraintName", keymap.Key);
            Assert.AreEqual("ConstraintType", keymap.Typekey);
        }