using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Text.RegularExpressions;
using SubSonic.Utilities;
namespace SubSonic
{
[Serializable]
public class TableSchema
{
[Serializable]
public class ManyToManyDetailsCollection : List<ManyToManyDetails>
{
}
[Serializable]
public class ManyToManyDetails
{
private string linksToTable;
public string LinksToTable
{
get { return linksToTable; }
set { linksToTable = value; }
}
private string linksToColum;
public string LinksToColumn
{
get { return linksToColum; }
set { linksToColum = value; }
}
private string mapTableName;
public string MapTableName
{
get { return mapTableName; }
set { mapTableName = value; }
}
}
[Serializable]
public class ManyToManyRelationship : AbstractTableSchema
{
public ManyToManyRelationship(string tableName, DataProvider dataProvider)
{
Provider = dataProvider;
mapTableName = tableName;
Name = mapTableName;
ClassName = TransformClassName(Name, false, TableType, Provider);
ClassNamePlural = TransformClassName(Name, false, TableType, Provider);
DisplayName = Utility.ParseCamelToProper(ClassName);
}
private string mapTableName;
public string MapTableName
{
get { return mapTableName; }
//set { mapTableName = value; }
}
private string mapTableLocalTableKeyColumn;
public string MapTableLocalTableKeyColumn
{
get { return mapTableLocalTableKeyColumn; }
set { mapTableLocalTableKeyColumn = value; }
}
private string mapTableForeignTableKeyColumn;
public string MapTableForeignTableKeyColumn
{
get { return mapTableForeignTableKeyColumn; }
set { mapTableForeignTableKeyColumn = value; }
}
private string foreignPrimaryKey;
public string ForeignPrimaryKey
{
get { return foreignPrimaryKey; }
set { foreignPrimaryKey = value; }
}
private string foreignTableName;
public string ForeignTableName
{
get { return foreignTableName; }
set
{
foreignTableName = value;
}
}
}
[Serializable]
public class ManyToManyRelationshipCollection : List<ManyToManyRelationship>
{
}
[Serializable]
public abstract class AbstractTableSchema
{
private DataProvider provider;
public DataProvider Provider
{
get { return provider; }
protected set { provider = value; }
}
private string _tableName;
public string TableName
{
get { return _tableName; }
set
{
_tableName = value;
className = TransformClassName(Name, false, tableType, Provider);
classNamePlural = TransformClassName(Name, true, tableType, Provider);
displayName = Utility.ParseCamelToProper(ClassName);
}
}
private TableType tableType;
public TableType TableType
{
get { return tableType; }
set { tableType = value; }
}
public string Name
{
get { return _tableName; }
set { TableName = value; }
}
private string className;
public string ClassName
{
get { return className; }
protected set { className = value; }
}
private string classNamePlural;
public string ClassNamePlural
{
get { return classNamePlural; }
protected set { classNamePlural = value; }
}
private string propertyName;
public string PropertyName
{
get { return propertyName; }
protected set { propertyName = value; }
}
private string displayName;
public string DisplayName
{
get { return displayName; }
protected set { displayName = value; }
}
private string schemaName;
public string SchemaName
{
get { return schemaName; }
set { schemaName = value; }
}
private ExtendedPropertyCollection extendedProperties = new ExtendedPropertyCollection();
public ExtendedPropertyCollection ExtendedProperties
{
get { return extendedProperties; }
set { extendedProperties = value; }
}
public static string TransformClassName(string name, bool isPlural, TableType tableType, DataProvider provider)
{
if(String.IsNullOrEmpty(name))
return string.Empty;
string newName = name;
if (tableType == TableType.Table)
{
newName = Utility.StripText(newName, provider.StripTableText);
}
else if (tableType == TableType.View)
{
newName = Utility.StripText(newName, provider.StripViewText);
}
newName = Utility.RegexTransform(newName, provider);
newName = Utility.GetProperName(newName, provider.RemoveUnderscores);
newName = Utility.IsStringNumeric(newName) ? "_" + newName : newName;
newName = Utility.StripNonAlphaNumeric(newName);
newName = newName.Trim();
if(!isPlural)
{
newName = provider.FixPluralClassNames ? Utility.PluralToSingular(newName) : newName;
}
return Utility.KeyWordCheck(newName, String.Empty, provider);
}
public void ApplyExtendedProperties()
{
ExtendedProperty epClassName = ExtendedProperty.GetExtendedProperty(ExtendedProperties, ExtendedPropertyName.SSX_TABLE_CLASS_NAME_SINGULAR);
ExtendedProperty epClassNamePlural = ExtendedProperty.GetExtendedProperty(ExtendedProperties, ExtendedPropertyName.SSX_TABLE_CLASS_NAME_PLURAL);
ExtendedProperty epDisplayName = ExtendedProperty.GetExtendedProperty(ExtendedProperties, ExtendedPropertyName.SSX_TABLE_DISPLAY_NAME);
if (epClassName != null)
className = epClassName.PropertyValue;
if (epClassNamePlural != null)
classNamePlural = epClassNamePlural.PropertyValue;
if (epDisplayName != null)
displayName = epDisplayName.PropertyValue;
}
}
[Serializable]
public class PrimaryKeyTable : AbstractTableSchema
{
public PrimaryKeyTable(DataProvider dataProvider)
{
Provider = dataProvider;
}
private string _columnName;
public string ColumnName
{
get { return _columnName; }
set
{
_columnName = value;
PropertyName = TableColumn.TransformPropertyName(_columnName, TableName, Provider);
}
}
}
public class PrimaryKeyTableCollection : List<PrimaryKeyTable>
{
}
[Serializable]
public class ForeignKeyTable : AbstractTableSchema
{
public ForeignKeyTable(DataProvider dataProvider)
{
Provider = dataProvider;
}
private string _columnName;
public string ColumnName
{
get { return _columnName; }
set
{
_columnName = value;
PropertyName = TableColumn.TransformPropertyName(_columnName, TableName, Provider);
}
}
}
public class ForeignKeyTableCollection : List<ForeignKeyTable>
{
}
[Serializable]
public class TableColumnSettingCollection : KeyedCollection<string, TableColumnSetting>
{
public bool IsDirty
{
get
{
foreach (TableColumnSetting setting in this)
{
if (setting.IsDirty)
return true;
}
return false;
}
set
{
foreach (TableColumnSetting setting in this)
{
setting.IsDirty = value;
}
}
}
protected override string GetKeyForItem(TableColumnSetting item)
{
return item.ColumnName;
}
public object GetValue(string columnName)
{
return this[columnName.ToLower()].CurrentValue;
}
public T GetValue<T>(string columnName)
{
columnName = columnName.ToLower();
object oVal = null;
try
{
oVal = this[columnName].CurrentValue;
}
catch
{
throw new Exception("There's no column called '" + columnName + "' for this object");
}
if(oVal == null || oVal == DBNull.Value)
{
return default(T);
}
Type type = typeof(T);
if(IsNullable(type) || type == typeof(object))
{
return (T)oVal;
}
Type valType = oVal.GetType();
if(valType == typeof(Byte[]))
{
return (T)Convert.ChangeType(oVal, valType);
}
return (T)Convert.ChangeType(oVal, type);
}
public static bool IsNullable(Type objType)
{
if(!objType.IsGenericType)
{
return false;
}
return objType.GetGenericTypeDefinition().Equals(typeof(Nullable<>));
}
public void SetValue(string columnName, object oVal)
{
columnName = columnName.ToLower(); //EK: Why is this necessary? This method is the only place where ColumnName is set.
if(!Contains(columnName))
{
Add(new TableColumnSetting(columnName, oVal));
}
else
{
this[columnName].CurrentValue = oVal;
}
}
}
/// <summary>
/// This is an intermediary class that holds the current value of a table column
/// for each object instance.
/// </summary>
[Serializable]
public class TableColumnSetting
{
public TableColumnSetting(string columnName, object currentValue)
{
_columnName = columnName;
_currentValue = currentValue;
}
private readonly string _columnName;
public string ColumnName
{
get { return _columnName; }
}
private object _currentValue;
public object CurrentValue
{
get { return _currentValue; }
set {
if (value == null && _currentValue == null)
return;
if (value != null)
{
if (value.Equals(_currentValue))
return;
}
_currentValue = value;
_isDirty = true;
}
}
private bool _isDirty = false;
public bool IsDirty
{
get { return _isDirty; }
set { _isDirty = value; }
}
}
[Serializable]
public class TableCollection : List<Table>
{
public Table this[string tableName]
{
get
{
Table result = null;
foreach(Table tbl in this)
{
if(Utility.IsMatch(tbl.Name, tableName))
{
result = tbl;
break;
}
}
return result;
}
set
{
int index = 0;
foreach(Table tbl in this)
{
if(Utility.IsMatch(tbl.Name, tableName))
{
this[index] = value;
break;
}
index++;
}
}
}
}
/// <summary>
/// Holds information about the base table - this class should be
/// static for each object
/// </summary>
[Serializable]
public class Table : AbstractTableSchema
{
public Table(DataProvider dataProvider)
{
Provider = dataProvider;
}
public Table(string tableName, TableType tblType, DataProvider dataProvider)
{
Provider = dataProvider;
TableType = tblType;
Name = tableName;
}
private ManyToManyRelationshipCollection manyToManys = new ManyToManyRelationshipCollection();
public ManyToManyRelationshipCollection ManyToManys
{
get { return manyToManys; }
set { manyToManys = value; }
}
private PrimaryKeyTableCollection _primaryKeys = new PrimaryKeyTableCollection();
public PrimaryKeyTableCollection PrimaryKeyTables
{
get { return _primaryKeys; }
set { _primaryKeys = value; }
}
private ForeignKeyTableCollection _foreignKeys = new ForeignKeyTableCollection();
public ForeignKeyTableCollection ForeignKeys
{
get { return _foreignKeys; }
set { _foreignKeys = value; }
}
public bool HasForeignKeys()
{
return ForeignKeys.Count > 0;
}
private bool _hasManyToMany = false;
public bool HasManyToMany
{
get { return _hasManyToMany; }
set { _hasManyToMany = value; }
}
private TableColumnCollection columns;
public TableColumnCollection Columns
{
get { return columns; }
set { columns = value; }
}
private TableColumn primaryKey;
public TableColumn PrimaryKey
{
get
{
if(columns != null)
{
primaryKey = columns.GetPrimaryKey();
}
return primaryKey;
}
}
private TableColumn[] primaryKeys;
public TableColumn[] PrimaryKeys
{
get
{
if (columns != null)
{
primaryKeys = columns.GetPrimaryKeys();
}
return primaryKeys;
}
}
public TableColumn GetColumn(string columnName)
{
TableColumn col = null;
foreach(TableColumn column in Columns)
{
if(Utility.IsMatch(column.ColumnName.Trim(), columnName.Trim()))
{
col = column;
break;
}
}
return col;
}
}
[Serializable]
public class TableColumnCollection : List<TableColumn>
{
#region Collection Methods
public bool Contains(string columnName)
{
bool bOut = false;
foreach(TableColumn col in this)
{
if(Utility.IsMatch(col.ColumnName, columnName))
{
bOut = true;
break;
}
}
return bOut;
}
public void Add(Table tbl, string name, DbType dbType, bool isNullable, bool isPrimaryKey, bool isForeignKey)
{
TableColumn col = new TableColumn(tbl);
col.IsPrimaryKey = isPrimaryKey;
col.IsForeignKey = isForeignKey;
col.IsNullable = isNullable;
col.DataType = dbType;
col.ColumnName = name;
if(!Contains(name))
{
Add(col);
}
}
public void Add(Table tbl, string name, DbType dbType, bool isNullable)
{
Add(tbl, name, dbType, isNullable, false, false);
}
#endregion
public TableColumn GetColumn(string columnName)
{
TableColumn coll = null;
foreach(TableColumn child in this)
{
if(Utility.IsMatch(child.ColumnName, columnName))
{
coll = child;
break;
}
}
return coll;
}
public TableColumn GetPrimaryKey()
{
TableColumn coll = null;
foreach(TableColumn child in this)
{
if(child.IsPrimaryKey)
{
coll = child;
break;
}
}
return coll;
}
public TableColumn[] GetPrimaryKeys()
{
List<TableColumn> list = new List<TableColumn>();
foreach (TableColumn child in this)
{
if (child.IsPrimaryKey)
{
list.Add(child);
}
}
return list.ToArray();
}
}
/// <summary>
/// A helper class to help define the columns in an underlying table
/// </summary>
[Serializable]
public class TableColumn
{
public TableColumn(Table tableSchema)
{
table = tableSchema;
}
public Type GetPropertyType()
{
string systemType = Utility.GetSystemType(dbType);
Type t = Type.GetType(systemType);
return t;
}
private string defaultSetting;
public string DefaultSetting {
get { return defaultSetting; }
set { defaultSetting = value; }
}
private Table table;
public Table Table
{
get { return table; }
}
private bool isForeignKey;
public bool IsForeignKey
{
get { return isForeignKey; }
set { isForeignKey = value; }
}
private string foreignKeyTableName;
public string ForeignKeyTableName
{
get { return foreignKeyTableName; }
set { foreignKeyTableName = value; }
}
private string schemaName;
public string SchemaName
{
get { return schemaName; }
set { schemaName = value; }
}
private bool isPrimaryKey;
public bool IsPrimaryKey
{
get { return isPrimaryKey; }
set { isPrimaryKey = value; }
}
private bool isNullable;
public bool IsNullable
{
get { return isNullable; }
set { isNullable = value; }
}
private bool isReadOnly;
public bool IsReadOnly
{
get { return isReadOnly; }
set { isReadOnly = value; }
}
private DbType dbType;
public DbType DataType
{
get { return dbType; }
set { dbType = value; }
}
private int maxLength;
public int MaxLength
{
get { return maxLength; }
set { maxLength = value; }
}
private string columnName;
public string ColumnName
{
get { return columnName; }
set
{
columnName = value;
string transformColumnName = columnName;
propertyName = TransformPropertyName(transformColumnName, Table.ClassName, table.Provider);
displayName = TransformPropertyName(transformColumnName, Table.ClassName, table.Provider);
displayName = Utility.ParseCamelToProper(displayName);
if((!Sugar.Validation.IsUpperCase(displayName)) && (IsPrimaryKey || IsForeignKey) && displayName.Length > 1)
{
string strEnd = displayName.Substring(displayName.Length - 2, 2);
if(Utility.IsMatch(strEnd, "id") && strEnd[0].ToString() == "I")
{
displayName = displayName.Substring(0, displayName.Length - 2);
}
}
parameterName = Utility.PrefixParameter(columnName, Table.Provider);
argumentName = "var" + propertyName;
}
}
private string parameterName;
public string ParameterName
{
get { return parameterName; }
}
private string propertyName;
public string PropertyName
{
get {
return propertyName;
}
}
private string displayName;
public string DisplayName
{
get { return displayName; }
}
private string argumentName;
public string ArgumentName
{
get { return argumentName; }
}
private bool autoIncrement;
public bool AutoIncrement
{
get { return autoIncrement; }
set { autoIncrement = value; }
}
private int numberScale;
public int NumberScale
{
get { return numberScale; }
set { numberScale = value; }
}
private int numberPrecision;
public int NumberPrecision
{
get { return numberPrecision; }
set { numberPrecision = value; }
}
public bool IsNumeric
{
get
{
return DataType == DbType.Currency ||
DataType == DbType.Decimal ||
DataType == DbType.Double ||
DataType == DbType.Int16 ||
DataType == DbType.Int32 ||
DataType == DbType.Int64 ||
DataType == DbType.Single ||
DataType == DbType.UInt16 ||
DataType == DbType.UInt32 ||
DataType == DbType.UInt64 ||
DataType == DbType.VarNumeric;
}
}
public bool IsDateTime
{
get
{
return DataType == DbType.DateTime ||
DataType == DbType.Time ||
DataType == DbType.Date;
}
}
public bool IsString
{
get
{
return DataType == DbType.AnsiString ||
DataType == DbType.AnsiStringFixedLength ||
DataType == DbType.String ||
DataType == DbType.StringFixedLength;
}
}
public static string TransformPropertyName(string name, string table, DataProvider provider)
{
if (String.IsNullOrEmpty(name))
return string.Empty;
string newName = name;
newName = Utility.StripText(newName, provider.StripColumnText);
newName = Utility.RegexTransform(newName, provider);
newName = Utility.GetProperName(newName, provider.RemoveUnderscores);
newName = Utility.IsStringNumeric(newName) ? "_" + newName : newName;
newName = Utility.StripNonAlphaNumeric(newName);
newName = newName.Trim();
return Utility.KeyWordCheck(newName, table, provider);
}
private ExtendedPropertyCollection extendedProperties = new ExtendedPropertyCollection();
public ExtendedPropertyCollection ExtendedProperties
{
get { return extendedProperties; }
set { extendedProperties = value; }
}
public void ApplyExtendedProperties()
{
ExtendedProperty epPropertyName = ExtendedProperty.GetExtendedProperty(ExtendedProperties, ExtendedPropertyName.SSX_COLUMN_PROPERTY_NAME);
ExtendedProperty epDisplayName = ExtendedProperty.GetExtendedProperty(ExtendedProperties, ExtendedPropertyName.SSX_COLUMN_DISPLAY_NAME);
if (epPropertyName != null)
propertyName = epPropertyName.PropertyValue;
if (epDisplayName != null)
displayName = epDisplayName.PropertyValue;
}
}
public class ExtendedPropertyCollection : KeyedCollection<string, ExtendedProperty>
{
protected override string GetKeyForItem(ExtendedProperty extendedProperty)
{
return extendedProperty.PropertyName;
}
}
public class ExtendedProperty
{
public ExtendedProperty(string name, string value)
{
propertyName = name;
propertyValue = value;
}
private string propertyName;
public string PropertyName
{
get { return propertyName; }
set { propertyName = value; }
}
private string propertyValue;
public string PropertyValue
{
get { return propertyValue; }
set { propertyValue = value; }
}
public static ExtendedProperty GetExtendedProperty(ExtendedPropertyCollection exPropCol, string extendedPropertyName)
{
ExtendedProperty exProperty = null;
if (exPropCol.Contains(extendedPropertyName))
{
exProperty = exPropCol[extendedPropertyName];
if (String.IsNullOrEmpty(exProperty.PropertyValue))
{
exProperty = null;
}
}
return exProperty;
}
}
}
}