/// <summary>
 /// Creates a ClassDeclaration.
 /// </summary>
 /// <param name="namespaceDeclaration">The NamespaceDeclaration instance the class is added to.</param>
 /// <param name="table">The database table the ClassDeclaration represents.</param>
 /// <returns>A reference to the ClassDeclaration instance that was created.</returns>
 protected override ClassDeclaration CreateClass(NamespaceDeclaration namespaceDeclaration, TableSchema table)
 {
     ClassDeclaration result = namespaceDeclaration.AddClass(this.NameProvider.GetClassName(table), true);
     ClassDeclaration baseType = new ClassDeclaration(this.ConfigOptions.BaseTypeName, new CodeDomTypeReference(result.FullName));
     result.InheritsFrom(baseType);
     return result;
 }
 protected override ClassDeclaration CreateClass(NamespaceDeclaration namespaceDeclaration, TableSchema table)
 {
     ClassDeclaration result = new ClassDeclaration(this.NameProvider.GetClassName(table.Name));
     result.IsPartial = true;
     namespaceDeclaration.AddClass(result);
     return result;
 }
 protected override ClassDeclaration AddMethods(ClassDeclaration classDecl, TableSchema table)
 {
     AddToDataMethod(classDecl, table);
     AddFromDataMethod(classDecl, table);
     AddPropertyChangedPlumbing(classDecl);
     AddCopyToMethod(classDecl, table);
     return classDecl;
 }
Beispiel #4
0
 /// <summary>
 /// Initializes a new instance of the ColumnSchema
 /// </summary>
 /// <param name="dbprovider">The DbProvider used for interrogating the datastore.</param>
 /// <param name="table">The TableSchema that contains the column.</param>
 /// <param name="sqlType">SqlDbType.</param>
 /// <param name="dataType">.NET DataType</param>
 /// <param name="name">Name of the column.</param>
 /// <param name="props">Any extended properties.</param>
 /// <param name="length">Length of the column if supported.</param>
 public ColumnSchema(IDbProvider dbprovider, TableSchema table, SqlDbType sqlType, Type dataType, string name, int length, Dictionary<string, object> props)
 {
     _table = table;
     _props = props;
     _sqlType = sqlType;
     _dataType = dataType;
     _name = name;
     _length = length;
     _dbprovider = dbprovider;
 }
 /// <summary>
 /// Creates a ClassDeclaration shell.
 /// </summary>
 /// <param name="nsdecl">NamespaceDeclaration the class is added.</param>
 /// <param name="table">Database table that the generated class will interact with.</param>
 /// <returns>The ClassDeclaration shell that was created.</returns>
 protected override ClassDeclaration CreateClass(NamespaceDeclaration nsdecl, TableSchema table)
 {
     ClassDeclaration result = nsdecl.AddClass(this.NameProvider.GetClassName(table), true);
     ClassDeclaration baseType = null;
     if (!String.IsNullOrEmpty(this.ConfigOptions.AbstractBaseName))
         baseType = new ClassDeclaration(this.ConfigOptions.AbstractBaseName, new CodeDomTypeReference(result.FullName));
     else
         baseType = new ClassDeclaration(this.ConfigOptions.BaseTypeName, new CodeDomTypeReference(result.FullName));
     result.InheritsFrom(baseType);
     return result;
 }
        /// <summary>
        /// Creates a ClassDeclaration.
        /// </summary>
        /// <param name="namespaceDeclaration">The NamespaceDeclaration instance the class is added to.</param>
        /// <param name="table">The database table the ClassDeclaration represents.</param>
        /// <returns>
        /// A reference to the ClassDeclaration instance that was created.
        /// </returns>
        protected override ClassDeclaration CreateClass(NamespaceDeclaration namespaceDeclaration, TableSchema table)
        {
            var result = namespaceDeclaration.AddClass(this.NameProvider.GetClassName(table), true);

            string baseTypeName = String.IsNullOrEmpty(ConfigOptions.AbstractBaseName)
                ? ConfigOptions.BaseTypeName
                : ConfigOptions.AbstractBaseName;

            var baseType = new ClassDeclaration(baseTypeName, new CodeDomTypeReference(result.FullName));
            result.InheritsFrom(baseType);
            return result;
        }
Beispiel #7
0
        private string GetNameField(string nameField, TableSchema tableSchema)
        {
            if (tableSchema == null || tableSchema.Columns == null || tableSchema.Columns.Count == 0)
            {
                return String.Empty;
            }

            string internalNameField = nameField;
            if (String.IsNullOrEmpty(internalNameField) || tableSchema.Columns[nameField] == null)
            {
                if (tableSchema.Columns["Label"] != null)
                {
                    internalNameField = "Label";
                }
                else if (tableSchema.Columns["Name"] != null)
                {
                    internalNameField = "Name";
                }
            }
            return internalNameField;
        }
        /// <summary>
        /// Gets the associations.
        /// </summary>
        /// <param name="table">The table.</param>
        /// <returns></returns>
        public virtual TableSchemaList GetAssociations(TableSchema table)
        {
            TableSchemaList result = new TableSchemaList();

            //find all tables that have 2 foreign keys, only 2 columns, and NO primary key
            var assocTables = from t in this.GetTableSchemas()
                              where t.PrimaryKey == null
                              && t.Columns.Count == 2
                              && t.ForeignKeys.Count == 2
                              select t;

            foreach (var tbl in assocTables)
            {
                if (tbl.ForeignKeys[0].PrimaryKeyTable.Name == table.Name
                    || tbl.ForeignKeys[1].PrimaryKeyTable.Name == table.Name)
                {
                    result.Add(tbl);
                }
            }

            return result;
        }
        protected override void CreateAssociationProperties(ClassDeclaration classDeclaration, TableSchema table)
        {
            if (classDeclaration == null || table == null || table.Associations.Count == 0)
                return;

            foreach (var assocTable in table.Associations)
            {
                Console.WriteLine("assocTable.Name=" + assocTable.Name);
                var otherTable = assocTable.ForeignKeys.Single(fk => { return fk.PrimaryKeyTable.Name != table.Name; }).PrimaryKeyTable;

                string propName = Inflector.Pluralize(this.NameProvider.GetPropertyName(otherTable.Name));
                string fieldName = Inflector.Pluralize(this.NameProvider.GetFieldName(otherTable.Name));
                var typeRef = new CodeDomTypeReference(typeof(IList<>).FullName, this.NameProvider.GetClassName(otherTable));
                var prop = classDeclaration.AddProperty(propName, fieldName, typeRef);
                prop.AddAttribute("Castle.ActiveRecord.HasAndBelongsToMany")
                    .AddArgument("typeof(" + this.NameProvider.GetClassName(otherTable) + ")")
                    .AddQuotedArgument("Table", assocTable.Name)
                    .AddQuotedArgument("ColumnKey", assocTable.ForeignKeys.Single(fk => { return fk.PrimaryKeyTable.Name == table.Name; }).Name)
                    .AddQuotedArgument("ColumnRef", assocTable.ForeignKeys.Single(fk => { return fk.PrimaryKeyTable.Name != table.Name; }).Name)
                    .AddArgument("Lazy = true");

            }
        }
        private void AddToDataMethod(ClassDeclaration classDecl, TableSchema table)
        {
            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = "ToData";
            string returnTypeName = this.ConfigOptions.DataNamespace + "." + this.NameProvider.GetClassName(table);
            method.ReturnType = new CodeTypeReference(returnTypeName);
            method.Attributes = MemberAttributes.Public | MemberAttributes.Static;

            string argName = this.NameProvider.GetArgumentName(table.Name);
            var parameter = new CodeParameterDeclarationExpression(this.NameProvider.GetClassName(table), argName);
            method.Parameters.Add(parameter);

            var ifargnull =
                new CodeConditionStatement(
                    new CodeSnippetExpression(argName + " == null"),
                    new CodeMethodReturnStatement(new CodeSnippetExpression("null")));
            method.Statements.Add(ifargnull);

            var initExpression = new CodeSnippetExpression(returnTypeName + ".Find(" + argName + ".ID) ?? new " + returnTypeName + "()");

            var methodResult = new CodeVariableDeclarationStatement(returnTypeName, "result", initExpression);
            method.Statements.Add(methodResult);

            //create a model based on what we just got from the database
            method.Statements.Add(new CodeCommentStatement("create a model based on what we just got from the database"));
            var internalModelDeclaration = new CodeVariableDeclarationStatement(classDecl.FullName, "modelFilledFromDatabase", new CodeMethodInvokeExpression(null, "FromData", new CodeVariableReferenceExpression("result")));
            method.Statements.Add(internalModelDeclaration);

            //copy the values from the model passed in to the model filled from the database
            method.Statements.Add(new CodeCommentStatement("copy the values from the model passed in to the model filled from the database"));
            var copyToCall = new CodeMethodInvokeExpression(new CodeArgumentReferenceExpression(argName), "CopyTo", new CodeVariableReferenceExpression("modelFilledFromDatabase"));
            method.Statements.Add(copyToCall);

            var modelTarget = new CodeVariableReferenceExpression("modelFilledFromDatabase");
            foreach (ColumnSchema column in table.NonKeyColumns)
            {
                string propertyName = this.NameProvider.GetPropertyName(column);
                var right = new CodePropertyReferenceExpression(modelTarget, propertyName);
                var left = new CodePropertyReferenceExpression(new CodeArgumentReferenceExpression("result"), propertyName);

                var ifpropchanged = new CodeConditionStatement(
                        new CodeMethodInvokeExpression(
                            new CodeCastExpression("EightyProofSolutions.BlogEngine.Core.Models.ITrackPropertyChanges", modelTarget),
                                "Changed",
                                new CodeSnippetExpression("\"" + propertyName + "\"")),
                            new CodeAssignStatement(left, right));

                method.Statements.Add(ifpropchanged);
            }

            foreach (ForeignKeyColumnSchema column in table.ForeignKeys)
            {
                //if the fk column name is CompanyID, the name of the property needs to be Company, so remove the ID
                string propertyName = this.NameProvider.GetPropertyName(column).Replace("ID", "");

                string targetTypeName = this.ConfigOptions.DataNamespace + "." + this.NameProvider.GetClassName(column.PrimaryKeyTable.Name);

                var ifpropchanged = new CodeConditionStatement(
                        new CodeMethodInvokeExpression(
                            new CodeCastExpression("EightyProofSolutions.BlogEngine.Core.Models.ITrackPropertyChanges", modelTarget),
                                "Changed",
                                new CodeSnippetExpression("\"" + propertyName + "\"")));

                var ifmodeltargetpropisnull = new CodeConditionStatement(
                    new CodeBinaryOperatorExpression(
                        new CodePropertyReferenceExpression(modelTarget, propertyName),
                        CodeBinaryOperatorType.ValueEquality,
                        new CodeSnippetExpression("null")));

                ifmodeltargetpropisnull.TrueStatements.Add(new CodeAssignStatement(
                    new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("result"), propertyName),
                    new CodeSnippetExpression("null")));

                ifmodeltargetpropisnull.FalseStatements.Add(
                    new CodeVariableDeclarationStatement(targetTypeName, Inflector.Camelize(propertyName),
                        new CodeObjectCreateExpression(targetTypeName)));

                ifmodeltargetpropisnull.FalseStatements.Add(
                    new CodeAssignStatement(
                        new CodePropertyReferenceExpression(new CodeVariableReferenceExpression(Inflector.Camelize(propertyName)), "ID"),
                        new CodePropertyReferenceExpression(new CodePropertyReferenceExpression(modelTarget, propertyName), "ID")));

                ifmodeltargetpropisnull.FalseStatements.Add(
                    new CodeAssignStatement(
                        new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("result"), propertyName),
                        new CodeVariableReferenceExpression(Inflector.Camelize(propertyName))));

                ifpropchanged.TrueStatements.Add(ifmodeltargetpropisnull);
                method.Statements.Add(ifpropchanged);
            }

            if (table.PrimaryKey != null)
            {
                string propertyName = "ID";
                var right = new CodePropertyReferenceExpression(new CodeArgumentReferenceExpression(argName), propertyName);
                var left = new CodePropertyReferenceExpression(new CodeArgumentReferenceExpression("result"), propertyName);
                method.Statements.Add(new CodeAssignStatement(left, right));
            }

            //((ITrackPropertyChanges)company).ChangedProperties.Clear();
            var clearProps = new CodeMethodInvokeExpression(
                new CodePropertyReferenceExpression(
                    new CodeCastExpression("EightyProofSolutions.BlogEngine.Core.Models.ITrackPropertyChanges", new CodeArgumentReferenceExpression(argName)), "ChangedProperties"), "Clear");

            method.Statements.Add(clearProps);

            method.Statements.Add(new CodeSnippetExpression("foreach (var kvp in ((EightyProofSolutions.BlogEngine.Core.Models.ITrackPropertyChanges)modelFilledFromDatabase).ChangedProperties){"));
            method.Statements.Add(new CodeSnippetExpression("\t((EightyProofSolutions.BlogEngine.Core.Models.ITrackPropertyChanges)" + argName + ").ChangedProperties.Add(kvp.Key, kvp.Value)"));
            method.Statements.Add(new CodeSnippetExpression("}"));

            //foreach (var kvp in ((ITrackPropertyChanges)modelFilledFromDatabase).ChangedProperties)
            //{
            //	((ITrackPropertyChanges)company).ChangedProperties.Add(kvp.Key, kvp.Value);
            //}

            var resultExpression = new CodeMethodReturnStatement(new CodeVariableReferenceExpression("result"));
            method.Statements.Add(resultExpression);

            classDecl.Members.Add(method);
        }
 /// <summary>
 /// Adds an attribute to a ClassDeclaration.
 /// </summary>
 /// <param name="classDeclaration">The ClassDeclaration instance the property is added to.</param>
 /// <param name="table">The database table the ClassDeclaration represents.</param>
 protected override void AddClassAttributes(ClassDeclaration classDeclaration, TableSchema table)
 {
     classDeclaration.AddAttribute("Castle.ActiveRecord.ActiveRecordAttribute").AddQuotedArgument(table.Name);
 }
        /// <summary>
        /// Gets the primary key for a table.
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        public virtual PrimaryKeyColumnSchema GetPrimaryKey(TableSchema table)
        {
            PrimaryKeyColumnSchema result = null;
            if (table == null)
                return result;

            string cmdtext = @"
            select
            columnproperty(object_id(c.table_name), c.column_name, 'IsIdentity') as is_identity,
            c.*
            from information_schema.table_constraints tc
            inner join information_schema.key_column_usage kcu
            on kcu.constraint_name = tc.constraint_name
            and kcu.table_name = tc.table_name
            inner join information_schema.columns c
            on c.table_name = kcu.table_name
            and c.column_name = kcu.column_name
            where tc.constraint_type = 'PRIMARY KEY'
            and c.table_name = @table_name
            ";
            using (SqlCommand cmd = new SqlCommand(cmdtext))
            {
                cmd.Parameters.Add("@table_name", SqlDbType.NVarChar, 128).Value = table.Name;
                using (IDataReader reader = this._helper.ExecuteReader(cmd))
                {
                    if (reader.Read())
                    {
                        SqlDbType sqlType = Enum<SqlDbType>.Parse(reader["DATA_TYPE"].ToString());
                        Type dataType = getDataType(reader["DATA_TYPE"].ToString());
                        string name = reader["COLUMN_NAME"].ToString();
                        Dictionary<string, object> props = new Dictionary<string, object>();
                        props.Add("is_identity", Convert.ToBoolean(reader["is_identity"]));
                        int length = reader["CHARACTER_MAXIMUM_LENGTH"] != DBNull.Value ? System.Convert.ToInt32(reader["CHARACTER_MAXIMUM_LENGTH"]) : -1;
                        props.Add("is_primary_key", true);
                        props.Add("is_foreign_key", false);
                        props.Add("is_nullable", (reader["is_nullable"].ToString().Equals("YES")));
                        result = new PrimaryKeyColumnSchema(this, table, sqlType, dataType, name, length, props);
                    }
                }

            }
            return result;
        }
 /// <summary>
 /// Adds an attribute to a ClassDeclaration.
 /// </summary>
 /// <param name="classDeclaration">The ClassDeclaration instance the property is added to.</param>
 /// <param name="table">The database table the ClassDeclaration represents.</param>
 protected abstract void AddClassAttributes(ClassDeclaration classDeclaration, TableSchema table);
 protected override void CreateAssociationProperties(ClassDeclaration classDeclaration, TableSchema table)
 {
     //throw new NotImplementedException();
 }
 /// <summary>
 /// Creates a property that maps to a table's primary key.
 /// </summary>
 /// <param name="cdecl">The ClassDeclaration that represents the database table.</param>
 /// <param name="table">The database table that contains the primary key we're mapping as a property.</param>
 protected override PropertyDeclaration CreatePrimaryKeyProperty(ClassDeclaration cdecl, TableSchema table)
 {
     PrimaryKeyColumnSchema pk = table.PrimaryKey;
     string propertyName = "ID";
     string fieldName = "_id"; // this.NameProvider.GetFieldName(pk);
     PropertyDeclaration pkprop = cdecl.AddProperty(propertyName, fieldName, pk.DataType);
     AttributeDeclaration pkatrrib = pkprop.AddAttribute("Castle.ActiveRecord.PrimaryKeyAttribute");
     // TODO: Remove this shit code
     if (pk.IsIdentity)
         pkatrrib.AddArgument("Castle.ActiveRecord.PrimaryKeyType.Identity");
     else
     {
         if (pk.SqlType == System.Data.SqlDbType.UniqueIdentifier)
             pkatrrib.AddArgument("Castle.ActiveRecord.PrimaryKeyType.GuidComb");
         else
             pkatrrib.AddArgument("Castle.ActiveRecord.PrimaryKeyType.Assigned");
     }
     pkatrrib.AddQuotedArgument((pk.Name));
     return pkprop;
 }
        /// <summary>
        /// Generates the test class for a table.
        /// </summary>
        /// <param name="writer">The writer to which the code is written.</param>
        /// <param name="namespaceName">The namespace containing the test class.</param>
        /// <param name="table">The table being tested.</param>
        public void Generate(TextWriter writer, string namespaceName, TableSchema table)
        {
            if (table == null)
                throw new ArgumentNullException("table");

            NamespaceDeclaration nstest = new NamespaceDeclaration(namespaceName + ".Tests");

            //declare the test class
            string typeName = this.NameProvider.GetClassName(table.Name);
            ClassDeclaration testclass = nstest.AddClass(typeName + "Tests", true);
            string targetTypeName = namespaceName + "." + typeName;
            testclass.InheritsFrom(new ClassDeclaration("ActiveRecordBaseTest", new CodeDomTypeReference(targetTypeName)));

            //create the test method
            MethodDeclaration testmeth = testclass.AddMethod(String.Format("Verify{0}", typeName)).Public();
            testmeth.AddAttribute("NUnit.Framework.TestAttribute");
            string fullName = namespaceName + "." + typeName;

            string fieldName = this.NameProvider.GetClassName(table.Name).Substring(0, 1).ToLower() + this.NameProvider.GetClassName(table.Name).Substring(1);
            testmeth.Declare(fieldName).New(new CodeDomTypeReference(fullName));//generates: Customer customer = new Customer();
            foreach (ColumnSchema column in table.NonKeyColumns)
            {
                string propertyName = this.NameProvider.GetPropertyName(column);
                string propertyValue = this.ValueProvider.GetValue(column);
                testmeth.Assign(fieldName).Property(propertyName).To(propertyValue);
            }
            testmeth.Call(fieldName, "Save");
            nstest.Imports("System");
            CodeBuilder builder = new CodeBuilder();
            builder.GenerateCode(writer, nstest);
        }
 /// <summary>
 /// When overridden in a child class, adds constructors to the class declaration.
 /// </summary>
 /// <param name="classDecl">The class declaration for which we're building constructors.</param>
 /// <param name="table">The table schema the class declaration represents.</param>
 /// <returns>The updated class declaration or null if it's not overridden.</returns>
 protected virtual ClassDeclaration CreateConstructors(ClassDeclaration classDecl, TableSchema table)
 {
     return null;
 }
        /// <summary>
        /// Creates the column list.
        /// </summary>
        /// <param name="table">The table.</param>
        /// <param name="classDecl">The class decl.</param>
        protected virtual void CreateColumnList(TableSchema table, ClassDeclaration classDecl)
        {
            ClassDeclaration cols = new ClassDeclaration(classDecl.Name + "Columns");
            var columns = table.Columns
                                            .GroupBy(c => { return c.Name; })
                                            .Select(g => { return g.ElementAt(0); });
            foreach (ColumnSchema column in columns)
            {
                string columnName = column.IsPrimaryKey ? "ID" : column.Name;
                FieldDeclaration field = new FieldDeclaration(columnName, typeof(string))
                                    .IsPublic()
                                    .InitializeTo("\"" + columnName + "\"");
                field.AddComment("This column is of type {0}{1}({2} in .NET) and can{3} be null.",
                    column.SqlType.ToString().ToLower(),
                    column.Length > 0 ? String.Format("({0})", column.Length) : "",
                    column.DataType.Name,
                    column.Nullable ? "" : "NOT");
                cols.AddField(field);

            }
            classDecl.AddClass(cols);

            FieldDeclaration columnsField = new FieldDeclaration("_columns", new CodeDomTypeReference(cols.Name)).IsStatic();
            columnsField.AddInitializer(new CodeDomTypeReference(cols.Name));
            PropertyDeclaration columnsProperty =
                new PropertyDeclaration("Columns", columnsField, new CodeDomTypeReference(cols.Name))
                .IsStatic().IsReadOnly();
            columnsProperty.AddComment("Gets an instance of the {0} class which contains all of the column names for {1}.", cols.Name, classDecl.Name);
            classDecl.AddProperty(columnsProperty);
        }
 /// <summary>
 /// Creates a ClassDeclaration.
 /// </summary>
 /// <param name="namespaceDeclaration">The NamespaceDeclaration instance the class is added to.</param>
 /// <param name="table">The database table the ClassDeclaration represents.</param>
 /// <returns>A reference to the ClassDeclaration instance that was created.</returns>
 protected abstract ClassDeclaration CreateClass(NamespaceDeclaration namespaceDeclaration, TableSchema table);
 /// <summary>
 /// Creates the association properties.
 /// </summary>
 /// <param name="classDeclaration">The class declaration.</param>
 /// <param name="table">The table.</param>
 protected abstract void CreateAssociationProperties(ClassDeclaration classDeclaration, TableSchema table);
 /// <summary>
 /// When overriden in a child class, adds methods to the class declaration.
 /// </summary>
 /// <param name="classDecl">The class declaration to which the methods are added.</param>
 /// <param name="table">The table schema the class declaration represents.</param>
 /// <returns>The updated class declaration or null if it's not overriden.</returns>
 protected virtual ClassDeclaration AddMethods(ClassDeclaration classDecl, TableSchema table)
 {
     return null;
 }
        /// <summary>
        /// Adds a prrimary key property to the ClassDeclaration.
        /// </summary>
        /// <param name="classDeclaration">The ClassDeclaration instance the property is added to.</param>
        /// <param name="table">The database table the ClassDeclaration represents.</param>
        protected override PropertyDeclaration CreatePrimaryKeyProperty(ClassDeclaration classDeclaration, TableSchema table)
        {
            PrimaryKeyColumnSchema pk = table.PrimaryKey;
            if (pk == null)
                return null;

            string propertyName = "Id";

            string fieldName = this.NameProvider.GetFieldName(pk);
            PropertyDeclaration pkprop = classDeclaration.AddProperty(propertyName, fieldName, pk.DataType);
            AttributeDeclaration pkatrrib = pkprop.AddAttribute("Castle.ActiveRecord.PrimaryKeyAttribute");
            // TODO: Remove this shit code
            if (pk.IsIdentity)
                pkatrrib.AddArgument("Castle.ActiveRecord.PrimaryKeyType.Identity");
            else
                pkatrrib.AddArgument("Castle.ActiveRecord.PrimaryKeyType.Assigned");
            pkatrrib.AddQuotedArgument((pk.Name));
            return pkprop;
        }
 ///// <summary>
 ///// Initializes a new Instance of the PrimaryKeyColumnSchema class.
 ///// </summary>
 //public PrimaryKeyColumnSchema()
 //{
 //    
 //}
 /// <summary>
 /// Initializes a new instance of a PrimaryKeyColumnSchema.
 /// </summary>
 /// <param name="dbprovider">The DbProvider used for interrogating the datastore.</param>
 /// <param name="table">The TableSchema that contains the column.</param>
 /// <param name="sqlType">SqlDbType.</param>
 /// <param name="dataType">.NET DataType</param>
 /// <param name="name">Name of the column.</param>
 /// <param name="props">Any extended properties.</param>
 /// <param name="length">Length of the column if supported.</param>
 public PrimaryKeyColumnSchema(IDbProvider dbprovider, TableSchema table, SqlDbType sqlType, Type dataType, string name, int length, Dictionary<string, object> props)
     : base(dbprovider, table, sqlType, dataType, name, length, props)
 {
 }
        /// <summary>
        /// Gets all of the columns for a table.
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        public virtual ColumnSchemaList GetColumnSchemas(TableSchema table)
        {
            string tableName = table.Name;
            ColumnSchemaList result = null;
            string cmdtext = @"
            select distinct
            case when cc.definition is null then 0 else 1 end as is_computed,
            case when cc.definition is null then 0 else 1 end as formula,
            isnull(columnproperty(object_id(c.table_name), c.column_name, 'IsIdentity'),0) as is_identity,
            case when (select tc.constraint_type from information_schema.table_constraints tc where tc.table_name = kcu.table_name and kcu.constraint_name = tc.constraint_name and tc.constraint_type = 'PRIMARY KEY') is null then 0 else 1 end as 'is_primary_key',
            case when (select tc.constraint_type from information_schema.table_constraints tc where tc.table_name = kcu.table_name and kcu.constraint_name = tc.constraint_name and tc.constraint_type = 'FOREIGN KEY') is null then 0 else 1 end as 'is_foreign_key',
            c.*
            from information_schema.columns c
            left join information_schema.key_column_usage kcu
            on c.table_name = kcu.table_name
            and c.column_name = kcu.column_name
            left join sys.computed_columns cc
            on cc.[object_id] = object_id(@table_name)
            and cc.[name] = c.column_name
            where c.table_name = @table_name
            ";
            try
            {
                using (SqlCommand cmd = new SqlCommand(cmdtext))
                {
                    cmd.Parameters.Add("@table_name", SqlDbType.NVarChar, 128).Value = tableName;
                    using (IDataReader reader = _helper.ExecuteReader(cmd))
                    {
                        while (reader.Read())
                        {
                            if (result == null) result = new ColumnSchemaList();
                            SqlDbType sqlType = getSqlDbType(reader["DATA_TYPE"].ToString());
                            Type dataType = getDataType(reader["DATA_TYPE"].ToString());
                            string name = reader["COLUMN_NAME"].ToString();
                            int length = reader["CHARACTER_MAXIMUM_LENGTH"] != DBNull.Value ? System.Convert.ToInt32(reader["CHARACTER_MAXIMUM_LENGTH"]) : -1;
                            if (length < 0 && dataType == typeof(string))
                                length = 8000; //patch for varchar(max), not sure if this works in all situations.

                            Dictionary<string, object> props = new Dictionary<string, object>();
                            props.Add("is_identity", Convert.ToBoolean(reader["is_identity"]));
                            props.Add("is_primary_key", Convert.ToBoolean(reader["is_primary_key"]));
                            props.Add("is_foreign_key", Convert.ToBoolean(reader["is_foreign_key"]));
                            props.Add("is_nullable", (reader["is_nullable"].ToString().Equals("YES")));
                            props.Add("is_computed", Convert.ToBoolean(reader["is_computed"]));
                            props.Add("formula", (reader["formula"] ?? "").ToString());
                            result.Add(new ColumnSchema(this, table, sqlType, dataType, name, length, props));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new SchemaProberException(String.Format("An error occurred while processing the table '{0}'", tableName), ex);
            }

            return result;
        }
 /// <summary>
 /// Add some class attributes.
 /// </summary>
 /// <param name="classDecl">The ClassDeclaration instance we're adding an attribute to.</param>
 /// <param name="table">The database table that the ClassDeclaration represents.</param>
 protected override void AddClassAttributes(ClassDeclaration classDecl, TableSchema table)
 {
     classDecl.AddAttribute("Castle.ActiveRecord.ActiveRecordAttribute").AddQuotedArgument(this.NameProvider.Escape(table.Name));
 }
        /// <summary>
        /// Gets all of the foreign keys within a table.
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        public virtual ForeignKeyColumnSchemaList GetForeignKeys(TableSchema table)
        {
            ForeignKeyColumnSchemaList result = new ForeignKeyColumnSchemaList();

            string cmdtext = @"
            select distinct
            col_name(fc.parent_object_id, fc.parent_column_id) as column_name,
            c.data_type,
            object_name (f.referenced_object_id) as primary_key_table,
            c.*
            from sys.foreign_keys as f
            inner join sys.foreign_key_columns as fc
            on f.object_id = fc.constraint_object_id
            inner join information_schema.columns c
            on c.column_name = col_name(fc.parent_object_id, fc.parent_column_id)
            and c.table_name = object_name(f.parent_object_id)
            where object_name(f.parent_object_id) = @table_name
            ";
            using (SqlCommand cmd = new SqlCommand(cmdtext))
            {
                cmd.Parameters.Add("@table_name", SqlDbType.NVarChar, 128).Value = table.Name;
                using (IDataReader reader = this._helper.ExecuteReader(cmd))
                {
                    while (reader.Read())
                    {
                        string columnName = reader["column_name"].ToString();
                        SqlDbType sqldatatype = Enum<SqlDbType>.Parse(reader["data_type"].ToString());
                        Type datatype = getDataType(reader["data_type"].ToString());
                        Dictionary<string, object> props = new Dictionary<string, object>();
                        props.Add("primary_key_table", reader["primary_key_table"].ToString());
                        int length = reader["CHARACTER_MAXIMUM_LENGTH"] != DBNull.Value ? System.Convert.ToInt32(reader["CHARACTER_MAXIMUM_LENGTH"]) : -1;
                        ForeignKeyColumnSchema column = new ForeignKeyColumnSchema(this, table, sqldatatype, datatype, columnName, length, props);
                        result.Add(column);
                    }
                }
            }
            return result;
        }
 /// <summary>
 /// Adds a prrimary key property to the ClassDeclaration.
 /// </summary>
 /// <param name="classDeclaration">The ClassDeclaration instance the property is added to.</param>
 /// <param name="table">The database table the ClassDeclaration represents.</param>
 protected abstract PropertyDeclaration CreatePrimaryKeyProperty(ClassDeclaration classDeclaration, TableSchema table);
 protected override ClassDeclaration CreateConstructors(ClassDeclaration classDecl, TableSchema table)
 {
     return classDecl;
 }
 /// <summary>
 /// Generates the test class for a table.
 /// </summary>
 /// <param name="path">The path where the code will be written.</param>
 /// <param name="namespaceName">The namespace the class will belong.</param>
 /// <param name="table">The table to generate test code for.</param>
 public void Generate(string path, string namespaceName, TableSchema table)
 {
     using (StreamWriter fileWriter = new StreamWriter(path, false))
     using (StringWriter codeWriter = new StringWriter())
     {
         this.Generate(codeWriter, namespaceName, table);
         fileWriter.Write(codeWriter.ToString());
     }
 }
        /// <summary>
        /// Generates the specified namespace declaration.
        /// </summary>
        /// <param name="namespaceDeclaration">The namespace declaration.</param>
        /// <param name="table">The table.</param>
        /// <returns></returns>
        public ClassDeclaration Generate(NamespaceDeclaration namespaceDeclaration, TableSchema table)
        {
            ClassDeclaration classDecl = this.CreateClass(namespaceDeclaration, table);
            this.AddClassAttributes(classDecl, table);
            this.CreatePrimaryKeyProperty(classDecl, table);

            foreach (ForeignKeyColumnSchema fk in table.ForeignKeys)
            {
                this.CreateForeignKey(classDecl, fk);
            }
            if (table.PrimaryKey != null && table.PrimaryKey.ForeignKeyReferences != null)
            {
                foreach (ForeignKeyColumnSchema foreignkey in table.PrimaryKey.ForeignKeyReferences)
                {
                    this.CreateForeignKeyReference(classDecl, foreignkey);
                }
            }
            if (table.NonKeyColumns != null)
            {
                foreach (ColumnSchema column in table.NonKeyColumns)
                {
                    this.CreateNonKeyProperty(classDecl, column);
                }
            }
            if (_configOptions.GenerateColumnList)
            {
                CreateColumnList(table, classDecl);
            }
            this.CreateConstructors(classDecl, table);
            this.CreateAssociationProperties(classDecl, table);
            this.AddMethods(classDecl, table);
            return classDecl;
        }