private MetadataDatabase FromCache() { if (UseCache == false) { return(null); } MetadataDatabase mdb = CacheMetadata(MetadataKey); if (mdb != null) { return(mdb); } if (!string.IsNullOrEmpty(FileName)) { mdb = SerializationExtensions.FromFile(FileName); CacheMetadata(MetadataKey, mdb); } return(mdb); }
private MetadataTable BuildMetadata(MetadataDatabase mdb, Microsoft.SqlServer.Management.Smo.Table table, bool PrimaryKeyIndexOnly = true, bool SelfJoin = false) { MetadataTable mt = null; List <VirtualForeignKey> VirtualKeys = new List <VirtualForeignKey>(); table.Refresh(); if (mdb.Tables.TryGetValue(table.Name, out mt)) { return(mt); } mt = new MetadataTable() { ID = table.ID, Schema = table.Schema, Name = table.Name, //Parent = mdb }; mt.TitleColumn = GetExtendedProperty("TitleColumn", table.ExtendedProperties); string[] values = GetExtendedProperty("DisplayName", table.ExtendedProperties, new char[] { '\r', '\n' }); if (values != null) { foreach (string value in values) { string[] v = value.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries); mt.DisplayNames.TryAdd(Convert.ToInt32(v[0]), v[1]); } } values = GetExtendedProperty("Lists", table.ExtendedProperties, new char[] { '\r', '\n' }); if (values != null) { foreach (string value in values) { string[] v = value.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries); List <string> v2 = v[1].Split(',').ToList(); if (!mt.ListDefinitions.TryAdd(v[0].Trim(), v2)) { throw new InvalidOperationException(string.Format("The TinySql.Lists extended property is invalid for the table '{0}'", table.Name)); } } } foreach (Microsoft.SqlServer.Management.Smo.Column column in table.Columns) { try { MetadataColumn col = new MetadataColumn() { ID = column.ID, Parent = mt, //Database = mdb, Name = column.Name, Collation = column.Collation, Default = column.Default, IsComputed = column.Computed, ComputedText = column.ComputedText, IsPrimaryKey = column.InPrimaryKey, IsIdentity = column.Identity, IsForeignKey = column.IsForeignKey, IdentityIncrement = column.IdentityIncrement, IdentitySeed = column.IdentitySeed, Nullable = column.Nullable, IsRowGuid = column.RowGuidCol }; BuildColumnDataType(col, column); values = GetExtendedProperty("DisplayName", column.ExtendedProperties, new char[] { '\r', '\n' }); if (values != null) { foreach (string value in values) { if (!value.Contains("=")) { col.DisplayNames.TryAdd(SqlBuilder.DefaultCulture.LCID, value); } else { string[] v = value.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries); col.DisplayNames.TryAdd(Convert.ToInt32(v[0]), v[1]); } } } col.IncludeColumns = GetExtendedProperty("IncludeColumns", column.ExtendedProperties, new char[] { ',' }); values = GetExtendedProperty("FK", column.ExtendedProperties, new char[] { '\r', '\n' }); if (values != null) { VirtualKeys.Add(new VirtualForeignKey() { Column = col, values = values }); col.IsForeignKey = true; } mt.Columns.AddOrUpdate(col.Name, col, (k, v) => { return(col); }); } catch (Exception exColumn) { throw new InvalidOperationException(string.Format("Unable to generate the column {0}", column.Name), exColumn); } } foreach (Index idx in table.Indexes) { if (!PrimaryKeyIndexOnly || idx.IndexKeyType == IndexKeyType.DriPrimaryKey) { Key key = new Key() { ID = idx.ID, Parent = mt, Database = mdb, Name = idx.Name, IsUnique = idx.IsUnique, IsPrimaryKey = idx.IndexKeyType == IndexKeyType.DriPrimaryKey }; foreach (IndexedColumn c in idx.IndexedColumns) { key.Columns.Add(mt[c.Name]); } mt.Indexes.AddOrUpdate(key.Name, key, (k, v) => { return(key); }); } } if (!SelfJoin) { foreach (ForeignKey FK in table.ForeignKeys) { MetadataForeignKey mfk = new MetadataForeignKey() { ID = FK.ID, Parent = mt, Database = mdb, Name = FK.Name, ReferencedKey = FK.ReferencedKey, ReferencedSchema = FK.ReferencedTableSchema, ReferencedTable = FK.ReferencedTable }; MetadataTable mtref = null; if (!mdb.Tables.TryGetValue(mfk.ReferencedSchema + "." + mfk.ReferencedTable, out mtref)) { bool self = false; if ((mfk.ReferencedSchema == mt.Schema && mfk.ReferencedTable == mt.Name) || TablesInProgress.Contains(mfk.ReferencedSchema + "." + mfk.ReferencedTable)) { self = true; } TablesInProgress.Add(mfk.ReferencedSchema + "." + mfk.ReferencedTable); mtref = BuildMetadata(mdb, mfk.ReferencedTable, mfk.ReferencedSchema, PrimaryKeyIndexOnly, self); } foreach (ForeignKeyColumn cc in FK.Columns) { mfk.ColumnReferences.Add(new MetadataColumnReference() { Name = cc.Name, Column = mt[cc.Name], ReferencedColumn = mtref[cc.ReferencedColumn] }); } mt.ForeignKeys.AddOrUpdate(mfk.Name, mfk, (key, existing) => { return(mfk); }); } } if (VirtualKeys.Count > 0) { BuildVirtualKeys(VirtualKeys, mt, mdb, PrimaryKeyIndexOnly); } mdb.Tables.AddOrUpdate(mt.Schema + "." + mt.Name, mt, (key, existing) => { return(mt); }); return(mt); }
private void BuildVirtualKeys(List <VirtualForeignKey> keys, MetadataTable mt, MetadataDatabase mdb, bool PrimaryKeyIndexOnly) { foreach (VirtualForeignKey vfk in keys) { MetadataForeignKey mfk = new MetadataForeignKey() { ID = 0, Name = vfk.values[0].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0], ReferencedKey = "", ReferencedTable = vfk.values[0].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[1], ReferencedSchema = vfk.values[0].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[2], Parent = mt, IsVirtual = true }; MetadataTable mtref = null; if (!mdb.Tables.TryGetValue(mfk.ReferencedSchema + "." + mfk.ReferencedTable, out mtref)) { bool self = false; if (mfk.ReferencedSchema == mt.Schema && mfk.ReferencedTable == mt.Name) { self = true; } mtref = BuildMetadata(mdb, mfk.ReferencedTable, mfk.ReferencedSchema, PrimaryKeyIndexOnly, self); } for (int i = 1; i < vfk.values.Length; i++) { MetadataColumnReference mcf = new MetadataColumnReference() { ReferencedColumn = mtref[vfk.values[i].Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries)[1]], }; string from = vfk.values[i].Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries)[0]; if (from.StartsWith("\"")) { MetadataColumn mcVirtual = new MetadataColumn() { Name = from, IsForeignKey = true, ID = 0, SqlDataType = SqlDbType.NVarChar, Nullable = false, Length = 0, IsComputed = true, DataType = typeof(string), }; mcf.Column = mcVirtual; mcf.Name = from; } else { mcf.Column = mt[from]; mcf.Name = mcf.Column.Name; } mfk.ColumnReferences.Add(mcf); } mt.ForeignKeys.AddOrUpdate(mfk.Name, mfk, (k, v) => { return(mfk); }); } }
public MetadataDatabase BuildMetadata(bool PrimaryKeyIndexOnly = true, string[] Tables = null, bool UpdateExisting = false) { MetadataDatabase mdb = FromCache(); string[] Changes = null; if (mdb != null && !UpdateExisting) { // mdb.Builder = builder; return(mdb); } Guid g = Guid.NewGuid(); try { g = SqlDatabase.DatabaseGuid; } catch (Exception) { } if (UpdateExisting) { if (mdb == null) { throw new ArgumentException("Update was specified but the metadata was not found in cache or file", "UpdateExisting"); } long v = GetVersion(); if (v <= mdb.Version) { RaiseUpdateEvent(100, "The database is up to date"); return(mdb); } else { Changes = GetChanges(new DateTime(mdb.Version)); RaiseUpdateEvent(0, string.Format("{0} Changed tables identified", Changes.Length)); foreach (string change in Changes) { MetadataTable mt = null; if (mdb.Tables.TryRemove(change, out mt)) { RaiseUpdateEvent(0, string.Format("{0} removed from Metadata pending update", change)); } else { throw new InvalidOperationException("Could not remove the table " + change + " pending update"); } } mdb.Version = v; } } else { mdb = new MetadataDatabase() { ID = g, Name = SqlDatabase.Name, Server = SqlServer.Name + (!string.IsNullOrEmpty(SqlServer.InstanceName) && SqlServer.Name.IndexOf('\\') == -1 ? "" : ""), Builder = builder, Version = GetVersion() }; } double t = 0; double total = Changes != null ? Changes.Length : Tables != null ? Tables.Length : SqlDatabase.Tables.Count + SqlDatabase.Views.Count; foreach (Microsoft.SqlServer.Management.Smo.Table table in SqlDatabase.Tables) { if (Tables == null || Tables.Contains(table.Name)) { if (Changes == null || Changes.Contains(table.Schema + "." + table.Name)) { table.Refresh(); BuildMetadata(mdb, table); if (MetadataUpdateEvent != null) { t++; RaiseUpdateEvent(Convert.ToInt32((t / total) * 100), table.Schema + "." + table.Name + " built"); } if (t == total) { break; } } } } foreach (Microsoft.SqlServer.Management.Smo.View view in SqlDatabase.Views) { if (view.IsSystemObject) { t++; continue; } if (Tables == null || Tables.Contains(view.Name)) { if (Changes == null || Changes.Contains(view.Schema + "." + view.Name)) { view.Refresh(); BuildMetadataView(mdb, view); if (MetadataUpdateEvent != null) { t++; RaiseUpdateEvent(Convert.ToInt32((t / total) * 100), view.Schema + "." + view.Name + " built"); } if (t == total) { break; } } } } ToCache(mdb); return(mdb); }