Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 359ad70

Browse files
committed
Merge pull request #178 from WimAtIHomer/master
Added SplitIntoMultipleFiles option to OrmLite.Poco.tt template
2 parents 8350d0a + afc61f7 commit 359ad70

File tree

2 files changed

+200
-17
lines changed

2 files changed

+200
-17
lines changed

src/T4/OrmLite.Core.ttinclude

Lines changed: 177 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<#@ template language="C#" hostspecific="True" #>
1+
<#@ template language="C#" hostspecific="True" #>
22
<#@ assembly name="EnvDTE" #>
33
<#@ assembly name="System.Core.dll" #>
44
<#@ assembly name="System.Data" #>
@@ -17,6 +17,7 @@
1717
<#@ import namespace="System.Text.RegularExpressions" #>
1818
<#@ import namespace="System.Configuration" #>
1919
<#@ import namespace="System.Windows.Forms" #>
20+
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
2021
<#+
2122

2223
/*
@@ -81,7 +82,6 @@
8182

8283
string ConnectionStringName = "";
8384
string Namespace = "";
84-
string RepoName = "";
8585
string ClassPrefix = "";
8686
string ClassSuffix = "";
8787
string SchemaName = null;
@@ -2362,4 +2362,178 @@ public static class Inflector {
23622362
#endregion
23632363
}
23642364

2365-
#>
2365+
/*
2366+
Manager.tt from Damien Guard: http://damieng.com/blog/2009/11/06/multiple-outputs-from-t4-made-easy-revisited
2367+
*/
2368+
2369+
2370+
// Manager class records the various blocks so it can split them up
2371+
class Manager {
2372+
private class Block {
2373+
public String Name;
2374+
public int Start, Length;
2375+
}
2376+
2377+
private Block currentBlock;
2378+
private List<Block> files = new List<Block>();
2379+
private Block footer = new Block();
2380+
private Block header = new Block();
2381+
private ITextTemplatingEngineHost host;
2382+
private StringBuilder template;
2383+
protected List<String> generatedFileNames = new List<String>();
2384+
2385+
public static Manager Create(ITextTemplatingEngineHost host, StringBuilder template) {
2386+
return (host is IServiceProvider) ? new VSManager(host, template) : new Manager(host, template);
2387+
}
2388+
2389+
public void KeepGeneratedFile(String name) {
2390+
name = Path.Combine(Path.GetDirectoryName(host.TemplateFile), name);
2391+
generatedFileNames.Add(name);
2392+
}
2393+
2394+
public void StartNewFile(String name) {
2395+
if (name == null)
2396+
throw new ArgumentNullException("name");
2397+
CurrentBlock = new Block { Name = name };
2398+
}
2399+
2400+
public void StartFooter() {
2401+
CurrentBlock = footer;
2402+
}
2403+
2404+
public void StartHeader() {
2405+
CurrentBlock = header;
2406+
}
2407+
2408+
public void EndBlock() {
2409+
if (CurrentBlock == null)
2410+
return;
2411+
CurrentBlock.Length = template.Length - CurrentBlock.Start;
2412+
if (CurrentBlock != header && CurrentBlock != footer)
2413+
files.Add(CurrentBlock);
2414+
currentBlock = null;
2415+
}
2416+
2417+
public virtual void Process(bool split) {
2418+
if (split) {
2419+
EndBlock();
2420+
String headerText = template.ToString(header.Start, header.Length);
2421+
String footerText = template.ToString(footer.Start, footer.Length);
2422+
String outputPath = Path.GetDirectoryName(host.TemplateFile);
2423+
files.Reverse();
2424+
foreach (Block block in files) {
2425+
String fileName = Path.Combine(outputPath, block.Name);
2426+
String content = headerText + template.ToString(block.Start, block.Length) + footerText;
2427+
generatedFileNames.Add(fileName);
2428+
CreateFile(fileName, content);
2429+
template.Remove(block.Start, block.Length);
2430+
}
2431+
}
2432+
}
2433+
2434+
protected virtual void CreateFile(String fileName, String content) {
2435+
if (IsFileContentDifferent(fileName, content))
2436+
File.WriteAllText(fileName, content);
2437+
}
2438+
2439+
public virtual String GetCustomToolNamespace(String fileName) {
2440+
return null;
2441+
}
2442+
2443+
public virtual String DefaultProjectNamespace {
2444+
get { return null; }
2445+
}
2446+
2447+
protected bool IsFileContentDifferent(String fileName, String newContent) {
2448+
return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent);
2449+
}
2450+
2451+
private Manager(ITextTemplatingEngineHost host, StringBuilder template) {
2452+
this.host = host;
2453+
this.template = template;
2454+
}
2455+
2456+
private Block CurrentBlock {
2457+
get { return currentBlock; }
2458+
set {
2459+
if (CurrentBlock != null)
2460+
EndBlock();
2461+
if (value != null)
2462+
value.Start = template.Length;
2463+
currentBlock = value;
2464+
}
2465+
}
2466+
2467+
private class VSManager : Manager {
2468+
private EnvDTE.ProjectItem templateProjectItem;
2469+
private EnvDTE.DTE dte;
2470+
private Action<String> checkOutAction;
2471+
private Action<IEnumerable<String>> projectSyncAction;
2472+
2473+
public override String DefaultProjectNamespace {
2474+
get {
2475+
return templateProjectItem.ContainingProject.Properties.Item("DefaultNamespace").Value.ToString();
2476+
}
2477+
}
2478+
2479+
public override String GetCustomToolNamespace(string fileName) {
2480+
return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString();
2481+
}
2482+
2483+
public override void Process(bool split) {
2484+
if (templateProjectItem.ProjectItems == null)
2485+
return;
2486+
base.Process(split);
2487+
projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null));
2488+
}
2489+
2490+
protected override void CreateFile(String fileName, String content) {
2491+
if (IsFileContentDifferent(fileName, content)) {
2492+
CheckoutFileIfRequired(fileName);
2493+
File.WriteAllText(fileName, content);
2494+
}
2495+
}
2496+
2497+
internal VSManager(ITextTemplatingEngineHost host, StringBuilder template)
2498+
: base(host, template) {
2499+
var hostServiceProvider = (IServiceProvider)host;
2500+
if (hostServiceProvider == null)
2501+
throw new ArgumentNullException("Could not obtain IServiceProvider");
2502+
dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));
2503+
if (dte == null)
2504+
throw new ArgumentNullException("Could not obtain DTE from host");
2505+
templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);
2506+
checkOutAction = (String fileName) => dte.SourceControl.CheckOutItem(fileName);
2507+
projectSyncAction = (IEnumerable<String> keepFileNames) => ProjectSync(templateProjectItem, keepFileNames);
2508+
}
2509+
2510+
private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable<String> keepFileNames) {
2511+
var keepFileNameSet = new HashSet<String>(keepFileNames);
2512+
var projectFiles = new Dictionary<String, EnvDTE.ProjectItem>();
2513+
var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.get_FileNames(0)) + ".";
2514+
foreach (EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems)
2515+
projectFiles.Add(projectItem.get_FileNames(0), projectItem);
2516+
2517+
// Remove unused items from the project
2518+
foreach (var pair in projectFiles)
2519+
if (!keepFileNames.Contains(pair.Key) && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalFilePrefix))
2520+
pair.Value.Delete();
2521+
2522+
// Add missing files to the project
2523+
foreach (String fileName in keepFileNameSet)
2524+
if (!projectFiles.ContainsKey(fileName))
2525+
templateProjectItem.ProjectItems.AddFromFile(fileName);
2526+
}
2527+
2528+
private void CheckoutFileIfRequired(String fileName) {
2529+
var sc = dte.SourceControl;
2530+
if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName))
2531+
checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null));
2532+
}
2533+
}
2534+
}
2535+
2536+
/*
2537+
End of Manager.tt
2538+
*/
2539+
#>

src/T4/OrmLite.Poco.tt

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
<#@ include file="OrmLite.Core.ttinclude" #>
1+
<#@ include file="OrmLite.Core.ttinclude" #>
22
<#
33
// Settings
4-
ConnectionStringName = ""; // Uses last connection string in config if not specified
5-
Namespace = "";
6-
RepoName = "";
7-
GenerateOperations = true;
8-
GeneratePocos = true;
9-
GenerateCommon = true;
4+
ConnectionStringName = ""; // Uses last connection string in config if not specified
5+
Namespace = "";
106
ClassPrefix = "";
117
ClassSuffix = "";
12-
TrackModifiedColumns = false;
8+
bool SplitIntoMultipleFiles = false;
139

1410
// Read schema
1511
var tables = LoadTables();
@@ -30,10 +26,16 @@
3026
#>
3127
<#
3228
if (string.IsNullOrEmpty(Namespace)) Namespace=ConnectionStringName;
33-
if (string.IsNullOrEmpty(RepoName) && !string.IsNullOrEmpty(ConnectionStringName)) RepoName=ConnectionStringName + "DB";
3429
if (string.IsNullOrEmpty(Namespace)) Namespace="OrmLitePoco";
35-
if (string.IsNullOrEmpty(RepoName)) RepoName="PocoDB";
36-
#>
30+
var manager = Manager.Create(Host, GenerationEnvironment);
31+
manager.StartHeader(); #>// <auto-generated />
32+
// This file was generated by a T4 template.
33+
// Don't change it directly as your change would get overwritten. Instead, make changes
34+
// to the .tt file (i.e. the T4 template) and save it to regenerate this file.
35+
36+
// Make sure the compiler doesn't complain about missing Xml comments
37+
#pragma warning disable 1591
38+
3739
using System;
3840
using System.Collections.Generic;
3941
using System.Linq;
@@ -45,11 +47,13 @@ using ServiceStack.DesignPatterns.Model;
4547

4648
namespace <#=Namespace #>
4749
{
50+
<#manager.EndBlock(); #>
4851
<#
4952
foreach(Table tbl in from t in tables where !t.Ignore select t)
5053
{
54+
manager.StartNewFile(tbl.Name + ".cs");
5155
#>
52-
56+
5357
[Alias("<#=tbl.Name#>")]
5458
public partial class <#=tbl.ClassName#><#if (tbl.HasPK()) { #> : IHasId<<#=tbl.PK.PropertyType#>><#}#>
5559
{
@@ -71,8 +75,13 @@ foreach(Column col in from c in tbl.Columns where !c.Ignore select c)
7175
<#}#>
7276
<# } #>
7377
}
74-
<# } #>
78+
<# manager.EndBlock(); #>
79+
<# } #>
80+
<#manager.StartFooter(); #>
7581
}
76-
<# } #>
82+
#pragma warning restore 1591
83+
<#manager.EndBlock(); #>
84+
<#manager.Process(SplitIntoMultipleFiles); #>
85+
<# } #>
7786

7887

0 commit comments

Comments
 (0)