<#@ include file="OrmLite.Core.ttinclude" #>
<#
	// Settings
	ConnectionStringName = "";			// Uses last connection string in config if not specified
	Namespace = "";
	ClassPrefix = "";
	ClassSuffix = "";
	bool SplitIntoMultipleFiles = false;		// if true: Generates one file for every class
	bool MakeSingular = true;			// if true: Changes the classname to singular if tablename is not singular
	bool UseIdAsPK = true;				// if true: Changes the primary key property name to Id
	bool GenerateConstructor = false;		// if true: Generates the default empty constructor
	bool UseSchemaAttribute = true;		// if true: Adds explicit '[Schema]' attribute
	bool CreateAutoQueryTypes = false; //if true: Will create <TypeName>Query types with all possible search fields explicitly typed
	bool AddNamedConnection = false; //if true: Adds NamedConnection attribute so AutoQuery will override default IDbConnection
	bool IncludeReferences = false; //if true: Addes References(typeof(ReferenceTableType)) to FKs
	string UseSpecificNamedConnection = ""; //if not null: Will use name provided as NamedConnection and AddNamedConnection = true, else ConnectionStringName is used as default NamedConnection
    // Read schema
	var tables = LoadTables(MakeSingular);


/*
	// Tweak Schema
	tables["tablename"].Ignore = true;							// To ignore a table
	tables["tablename"].ClassName = "newname";					// To change the class name of a table
	tables["tablename"]["columnname"].Ignore = true;			// To ignore a column
	tables["tablename"]["columnname"].PropertyName="newname";	// To change the property name of a column
	tables["tablename"]["columnname"].PropertyType="bool";		// To change the property type of a column
*/

	// Generate output
	if (tables.Count>0)
	{
#>
<#
if (string.IsNullOrEmpty(Namespace)) Namespace=ConnectionStringName;
if (string.IsNullOrEmpty(Namespace)) Namespace="OrmLitePoco";
var manager = Manager.Create(Host, GenerationEnvironment);
manager.StartHeader(true);
#>
// <auto-generated />
// This file was generated by a T4 template.
// Don't change it directly as your change would get overwritten.  Instead, make changes
// to the .tt file (i.e. the T4 template) and save it to regenerate this file.

// Make sure the compiler doesn't complain about missing Xml comments
#pragma warning disable 1591

using System;

using ServiceStack.DataAnnotations;
using ServiceStack.Model;
using ServiceStack;

namespace <#=Namespace #>
{
<#manager.EndBlock(); #>
<#
foreach(Table tbl in from t in tables where !t.Ignore select t)
{
manager.StartNewFile(tbl.Name + ".cs");
#>
<#if (CreateAutoQueryTypes && AddNamedConnection) {#>
	[NamedConnection("<#=!string.IsNullOrEmpty(UseSpecificNamedConnection) ? UseSpecificNamedConnection : ConnectionStringName#>")]
	<#}#>
<# if (MakeSingular) {#>
	[Alias("<#=tbl.Name#>")]
<#}#>
<# if (UseSchemaAttribute && !string.IsNullOrEmpty(tbl.Schema) && tbl.Schema != "dbo") {#>
	[Schema("<#=tbl.Schema#>")]
<#}#>
    public partial class <#=tbl.ClassName#><#if (tbl.HasPK() && UseIdAsPK) { #> : IHasId<<#=tbl.PK.PropertyType#>><#}#> 
    {
<# if (GenerateConstructor) { #>
		public <#=tbl.ClassName#>()
		{
		}

<# }
var priorProperyNames = new List<string>();
foreach(Column col in from c in tbl.Columns where !c.Ignore select c)
{
if (priorProperyNames.Contains(col.PropertyName)) //Change duplicate style names
{
	col.PropertyName = "_" + col.PropertyName;
}
priorProperyNames.Add(col.PropertyName);
 if ((col.Name!=col.PropertyName) || (col.IsPK && UseIdAsPK)) { #>
        [Alias("<#=col.Name#>")]
<# }  if (col.PropertyType == "string" && col.Size > 0) { #>
        [StringLength(<#=col.Size#>)]
<# }  if (col.IsAutoIncrement) { #>
        [AutoIncrement]
<# }  if (col.IsComputed) { #>
                 [Compute]        
 <# }  if (IncludeReferences && tbl.FKeys != null && tbl.FKeys.Any(x => x.FromColumn ==  col.PropertyName)) { 
 	   var toTable = MakeSingular ? tbl.FKeys.First(x => x.FromColumn == col.PropertyName).ToTableSingular : tbl.FKeys.First(x => x.FromColumn == col.PropertyName).ToTable;#>
        [References(typeof(<#=ClassPrefix + toTable + ClassSuffix#>))]
<# }  if (col.IsNullable != true && col.IsAutoIncrement != true) { #>
        [Required]
<# } if (!col.IsPK){#>
        public <#=col.ProperPropertyType#> <#=col.PropertyName#> { get; set; }
<# } if (col.IsPK && UseIdAsPK) { #>
        public <#=col.ProperPropertyType#> Id { get; set; }
<# } if (col.IsPK && !UseIdAsPK) { #>
		[PrimaryKey]
        public <#=col.ProperPropertyType#> <#=col.PropertyName#> { get; set; }
<# } #>
<# } #>
    }

<#if (CreateAutoQueryTypes) {#>
	public partial class <#=tbl.ClassName#>Query: QueryDb<<#=tbl.ClassName#>>
	{
<#foreach(Column col in from c in tbl.Columns where !c.Ignore select c)
{
var ormName = (col.IsPK && UseIdAsPK) ? "Id" : col.PropertyName;
var isString = col.ProperPropertyType == "string";
var nullablePropType = col.ProperPropertyType.Replace("?","") + "?";
var isArray = col.ProperPropertyType.Contains("[]");
var isBool = col.ProperPropertyType.Contains("bool");
var isGuid = col.ProperPropertyType.Contains("Guid");
 if (!col.IsPK){#>
        public <#=!isArray && !isString ? nullablePropType : col.ProperPropertyType#> <#=ormName#> { get; set; }
<# } if (col.IsPK && UseIdAsPK) { #>
        public <#=isString ? "string" : nullablePropType#> Id { get; set;}
<# } if (col.IsPK && !UseIdAsPK) { #> 
        public <#=isString ? "string" : nullablePropType#> <#=col.PropertyName#> { get; set; }<# } 
 
if (isString){ #>  
	    public <#=col.ProperPropertyType#> <#=ormName#>StartsWith { get; set; }
		public <#=col.ProperPropertyType#> <#=ormName#>EndsWith { get; set; }
		public <#=col.ProperPropertyType#> <#=ormName#>Contains { get; set; }
		public <#=col.ProperPropertyType#> <#=ormName#>Like { get; set; } 
		public <#=col.ProperPropertyType#>[] <#=ormName#>Between { get; set; }
		public <#=col.ProperPropertyType#>[] <#=ormName#>In { get; set; }
<#} 
else if (!isArray && !isBool) { if (!isGuid) {#>  
	    public <#=nullablePropType#> <#=ormName#>GreaterThanOrEqualTo { get; set; }
		public <#=nullablePropType#> <#=ormName#>GreaterThan { get; set; }
		public <#=nullablePropType#> <#=ormName#>LessThan { get; set; }
		public <#=nullablePropType#> <#=ormName#>LessThanOrEqualTo { get; set; }
		public <#=nullablePropType#> <#=ormName#>NotEqualTo { get; set; }
		public <#=col.ProperPropertyType#>[] <#=ormName#>Between { get; set; }
<#}#>
		public <#=col.ProperPropertyType#>[] <#=ormName#>In { get; set; }
<#}#>
 
<# } #>
}
	<#}#>
<#  manager.EndBlock(); #>
<#  }   #>
<#manager.StartFooter(true); #>
}
#pragma warning restore 1591
<#manager.EndBlock(); #>
<#manager.Process(SplitIntoMultipleFiles, true); #>
<#  }   #>
