You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

314 lines
16 KiB

using OpenDBDiff.Schema.Errors;
using OpenDBDiff.Schema.Events;
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;
using System.Linq;
using Constraint = OpenDBDiff.Schema.SQLServer.Generates.Model.Constraint;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateTables
{
private int colIDIndex = -1;
private int colNameIndex = -1;
private int colFormulaIndex = -1;
private int colIsPersistedIndex = -1;
private int colIsComputedIndex = -1;
private int colNullableIndex = -1;
private int colXmlSchemaIndex = -1;
private int colIs_xml_documentIndex = -1;
private int colPrecisionIndex = -1;
private int colScaleIndex = -1;
private int colDataUserTypeIdIndex = -1;
private int colIsUserDefinedTypeIndex = -1;
private int colSizeIndex = -1;
private int colHasIndexIndex = -1;
private int colHasComputedFormulaIndex = -1;
private int colIsRowGuidIndex = -1;
private int colTypeIndex = -1;
private int colOwnerType = -1;
private int colis_sparseIndex = -1;
private int colIs_FileStream = -1;
private int colDefaultIdIndex = -1;
private int colDefaultNameIndex = -1;
private int colDefaultDefinitionIndex = -1;
private int colrule_object_idIndex = -1;
private int colIsIdentityReplIndex = -1;
private int colCollationIndex = -1;
private int colIsIdentityIndex = -1;
private int colIdentSeedIndex = -1;
private int colIdentIncrementIndex = -1;
private int TableIdIndex = -1;
private int TableNameIndex = -1;
private int TableOwnerIndex = -1;
private int TableHasChangeTracking = -1;
private int TableHasChangeTrackingTrackColumn = -1;
private int TableLockEscalation = -1;
private int Text_In_Row_limitIndex = -1;
private int HasClusteredIndexIndex = -1;
private int large_value_types_out_of_rowIndex = -1;
private int HasVarDecimalIndex = -1;
private int FileGroupIndex = -1;
private int FileGroupTextIndex = -1;
private int FileGroupStreamIndex = -1;
private Generate root;
public GenerateTables(Generate root)
{
this.root = root;
}
private void InitTableIndex(Database database, IDataRecord reader)
{
if (reader == null) throw new ArgumentNullException("reader");
if (TableIdIndex == -1)
{
TableIdIndex = reader.GetOrdinal("TableId");
TableNameIndex = reader.GetOrdinal("TableName");
TableOwnerIndex = reader.GetOrdinal("TableOwner");
Text_In_Row_limitIndex = reader.GetOrdinal("Text_In_Row_limit");
HasClusteredIndexIndex = reader.GetOrdinal("HasClusteredIndex");
large_value_types_out_of_rowIndex = reader.GetOrdinal("large_value_types_out_of_row");
HasVarDecimalIndex = reader.GetOrdinal("HasVarDecimal");
FileGroupIndex = reader.GetOrdinal("FileGroup");
FileGroupTextIndex = reader.GetOrdinal("FileGroupText");
if (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008)
{
FileGroupStreamIndex = reader.GetOrdinal("FileGroupStream");
TableHasChangeTracking = reader.GetOrdinal("HasChangeTracking");
TableHasChangeTrackingTrackColumn = reader.GetOrdinal("HasChangeTrackingTrackColumn");
TableLockEscalation = reader.GetOrdinal("lock_escalation_desc");
}
}
}
private void InitColIndex(Database database, IDataRecord reader)
{
if (reader == null) throw new ArgumentNullException("reader");
if (colNameIndex == -1)
{
colIDIndex = reader.GetOrdinal("ID");
colNameIndex = reader.GetOrdinal("Name");
colFormulaIndex = reader.GetOrdinal("Formula");
colIsPersistedIndex = reader.GetOrdinal("FormulaPersisted");
colIsComputedIndex = reader.GetOrdinal("IsComputed");
colNullableIndex = reader.GetOrdinal("IsNullable");
colOwnerType = reader.GetOrdinal("OwnerType");
colXmlSchemaIndex = reader.GetOrdinal("XmlSchema");
colIs_xml_documentIndex = reader.GetOrdinal("Is_xml_document");
colPrecisionIndex = reader.GetOrdinal("Precision");
colScaleIndex = reader.GetOrdinal("Scale");
colDataUserTypeIdIndex = reader.GetOrdinal("user_type_id");
colIsUserDefinedTypeIndex = reader.GetOrdinal("is_user_defined");
colSizeIndex = reader.GetOrdinal("Size");
colHasIndexIndex = reader.GetOrdinal("HasIndex");
colHasComputedFormulaIndex = reader.GetOrdinal("HasComputedFormula");
colIsRowGuidIndex = reader.GetOrdinal("IsRowGuid");
colTypeIndex = reader.GetOrdinal("Type");
colDefaultIdIndex = reader.GetOrdinal("DefaultId");
colDefaultNameIndex = reader.GetOrdinal("DefaultName");
colDefaultDefinitionIndex = reader.GetOrdinal("DefaultDefinition");
colrule_object_idIndex = reader.GetOrdinal("rule_object_id");
colIsIdentityReplIndex = reader.GetOrdinal("IsIdentityRepl");
colCollationIndex = reader.GetOrdinal("Collation");
colIsIdentityIndex = reader.GetOrdinal("IsIdentity");
colIdentSeedIndex = reader.GetOrdinal("IdentSeed");
colIdentIncrementIndex = reader.GetOrdinal("IdentIncrement");
if (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008)
{
colis_sparseIndex = reader.GetOrdinal("is_sparse");
colIs_FileStream = reader.GetOrdinal("is_filestream");
}
}
}
private void FillColumn<T>(ITable<T> table, SqlDataReader reader) where T : ISchemaBase
{
Database database = (Database)table.Parent;
InitColIndex(database, reader);
Column col = new Column((ISchemaBase)table);
col.Id = (int)reader[colIDIndex];
if (database.Options.Ignore.FilterColumnOrder)
col.Position = table.Columns.Count + 1;
if (database.Options.Ignore.FilterColumnCollation)
col.Collation = (string)reader[colCollationIndex];
if (database.Options.Ignore.FilterColumnIdentity)
{
col.IsIdentity = (bool)reader[colIsIdentityIndex];
if ((col.IsIdentity) || (col.IsIdentityForReplication))
{
if (!reader.IsDBNull(colIdentSeedIndex))
col.IdentitySeed = (long)(decimal)reader[colIdentSeedIndex];
else
col.IdentitySeed = 1;
if (!reader.IsDBNull(colIdentIncrementIndex))
col.IdentityIncrement = (int)(decimal)reader[colIdentIncrementIndex];
else
col.IdentityIncrement = 1;
}
if (database.Options.Ignore.FilterNotForReplication)
col.IsIdentityForReplication = ((int)reader[colIsIdentityReplIndex] == 1);
}
col.Name = (string)reader[colNameIndex];
col.Owner = table.Owner;
col.ComputedFormula = (string)reader[colFormulaIndex];
col.IsPersisted = (bool)reader[colIsPersistedIndex];
col.IsComputed = (bool)reader[colIsComputedIndex];
col.IsNullable = (bool)reader[colNullableIndex];
col.XmlSchema = reader[colXmlSchemaIndex].ToString();
col.IsXmlDocument = (bool)reader[colIs_xml_documentIndex];
col.Precision = (byte)reader[colPrecisionIndex];
col.Scale = (byte)reader[colScaleIndex];
col.DataUserTypeId = (int)reader[colDataUserTypeIdIndex];
col.IsUserDefinedType = (bool)reader[colIsUserDefinedTypeIndex];
if (!String.IsNullOrEmpty(reader[colSizeIndex].ToString()))
col.Size = (short)reader[colSizeIndex];
col.HasIndexDependencies = ((int)reader[colHasIndexIndex] == 1);
col.HasComputedDependencies = ((int)reader[colHasComputedFormulaIndex] == 1);
col.IsRowGuid = (bool)reader[colIsRowGuidIndex];
if (col.IsUserDefinedType)
col.Type = "[" + (string)reader[colOwnerType] + "].[" + (string)reader[colTypeIndex] + "]";
else
col.Type = (string)reader[colTypeIndex];
if (((Database)table.Parent).Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008)
{
col.IsSparse = (bool)reader[colis_sparseIndex];
col.IsFileStream = (bool)reader[colIs_FileStream];
}
if ((int)reader[colDefaultIdIndex] != 0)
{
col.DefaultConstraint = new ColumnConstraint(col)
{
Id = (int)reader[colDefaultIdIndex],
Owner = table.Owner,
Name = (string)reader[colDefaultNameIndex],
Type = Constraint.ConstraintType.Default,
Definition = (string)reader[colDefaultDefinitionIndex]
};
}
if ((int)reader[colrule_object_idIndex] != 0)
col.Rule = ((Database)table.Parent).Rules.Find((int)reader[colrule_object_idIndex]);
table.Columns.Add(col);
}
public void Fill(Database database, string connectionString, List<MessageLog> messages)
{
try
{
root.RaiseOnReading(new ProgressEventArgs("Reading tables...", Constants.READING_TABLES));
FillTables(database, connectionString);
if (database.Tables.Any() || database.TablesTypes.Any())
{
if (database.Options.Ignore.FilterConstraint)
(new GenerateConstraint(root)).Fill(database, connectionString);
}
}
catch (Exception ex)
{
messages.Add(new MessageLog(ex.Message, ex.StackTrace, MessageLog.LogType.Error));
}
}
private void FillTables(Database database, string connectionString)
{
int textInRow;
Boolean largeValues;
Boolean varDecimal;
int lastObjectId = 0;
bool isTable = true;
ISchemaBase item = null;
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(TableSQLCommand.GetTableDetail(database.Info.Version, database.Info.Edition), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
InitTableIndex(database, reader);
root.RaiseOnReadingOne(reader[TableNameIndex]);
if (lastObjectId != (int)reader[TableIdIndex])
{
lastObjectId = (int)reader[TableIdIndex];
isTable = reader["ObjectType"].ToString().Trim().Equals("U");
if (isTable)
{
item = new Table(database);
item.Id = (int)reader[TableIdIndex];
item.Name = (string)reader[TableNameIndex];
item.Owner = (string)reader[TableOwnerIndex];
((Table)item).HasClusteredIndex = (int)reader[HasClusteredIndexIndex] == 1;
textInRow = (int)reader[Text_In_Row_limitIndex];
largeValues = (Boolean)reader[large_value_types_out_of_rowIndex];
varDecimal = ((int)reader[HasVarDecimalIndex]) == 1;
if (database.Options.Ignore.FilterTableFileGroup)
{
((Table)item).FileGroup = (string)reader[FileGroupIndex];
((Table)item).FileGroupText = (string)reader[FileGroupTextIndex];
if (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008)
{
if (database.Options.Ignore.FilterTableChangeTracking)
{
((Table)item).FileGroupStream = (string)reader[FileGroupStreamIndex];
((Table)item).HasChangeTracking = ((int)reader[TableHasChangeTracking]) == 1;
((Table)item).HasChangeTrackingTrackColumn = ((int)reader[TableHasChangeTrackingTrackColumn]) == 1;
}
}
}
if (database.Options.Ignore.FilterTableOption)
{
if (textInRow > 0) ((Table)item).Options.Add(new TableOption("TextInRow", textInRow.ToString(CultureInfo.InvariantCulture), item));
if (largeValues) ((Table)item).Options.Add(new TableOption("LargeValues", "1", item));
if (varDecimal) ((Table)item).Options.Add(new TableOption("VarDecimal", "1", item));
}
if ((database.Options.Ignore.FilterTableLockEscalation) && (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008))
((Table)item).Options.Add(new TableOption("LockEscalation", (string)reader[TableLockEscalation], item));
else
((Table)item).Options.Add(new TableOption("LockEscalation", "TABLE", item));
database.Tables.Add((Table)item);
}
else
{
item = new TableType(database)
{
Id = (int)reader[TableIdIndex],
Name = (string)reader[TableNameIndex],
Owner = (string)reader[TableOwnerIndex]
};
database.TablesTypes.Add((TableType)item);
}
}
if (isTable)
{
if (database.Options.Ignore.FilterTable)
FillColumn((ITable<Table>)item, reader);
}
else
{
if (database.Options.Ignore.FilterUserDataType)
FillColumn((ITable<TableType>)item, reader);
}
}
}
}
}
//tables.ToSQL();
}
}
}