<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>code-generation &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://en.wordpress.com/tag/code-generation/</link>
	<description>Feed of posts on WordPress.com tagged "code-generation"</description>
	<pubDate>Mon, 30 Nov 2009 04:45:22 +0000</pubDate>

	<generator>http://en.wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[Generating a model from the Database using AjGenesis]]></title>
<link>http://ajlopez.wordpress.com/2009/11/28/generating-a-model-from-the-database-using-ajgenesis/</link>
<pubDate>Sat, 28 Nov 2009 22:46:07 +0000</pubDate>
<dc:creator>ajlopez</dc:creator>
<guid>http://ajlopez.wordpress.com/2009/11/28/generating-a-model-from-the-database-using-ajgenesis/</guid>
<description><![CDATA[AjGenesis, my code generation open source project, use tasks, templates and a free model, to generat]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>AjGenesis, my code generation open source project, use tasks, templates and a free model, to generate text artifacts, usually source code. Most of the examples use models serialized as XML or text files. But you can use anything as the initial input. Even a model could be the output of this process. Month ago, I wrote about <a href="http://ajlopez.wordpress.com/2008/04/21/ajgenesis-generating-the-model-from-the-database/" target="_blank">generating the model from the database</a>. In my opinion, the database is not the more expressive model to use as starting point, but it is an ubiquitous one (you should admit: I’m improving my English vocabulary…;-)</p>
<p>In my current agile project, the team took the database as the base model. Actually, we are using a more abstract model, but the database was a good asset to use as first model.</p>
<p>So, I back to play with my old example, and improved it. You can download the current example from my Skydrive <a href="http://cid-9f903f3d6db0c176.skydrive.live.com/self.aspx/Examples/AjGenesis/DatabaseExample01.zip" target="_blank">DatabaseExample01.zip</a>. (the code in flux is in the code repository at Codeplex, under examples\DatabaseExamples).</p>
<p>After download and expand it, you have the folders:</p>
<p><img src="http://www.ajlopez.com/images/articles2/ajgenesisdb04.png" /> </p>
<p>The content of Projects\Northwind\Metadata.xml:</p>
<pre>
<pre style="background-color:#ffffff;width:100%;font-family:consolas;font-size:12px;margin:0;"><span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Metadata</span><span style="color:#0000ff;">&#62;</span>
  <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Project</span><span style="color:#0000ff;">&#62;</span>
    <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Name</span><span style="color:#0000ff;">&#62;</span>Northwind<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Name</span><span style="color:#0000ff;">&#62;</span>
  <span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Project</span><span style="color:#0000ff;">&#62;</span>
  <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Database</span><span style="color:#0000ff;">&#62;</span>
    <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Name</span><span style="color:#0000ff;">&#62;</span>Northwind<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Name</span><span style="color:#0000ff;">&#62;</span>
    <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">ConnectionString</span><span style="color:#0000ff;">&#62;</span>server=.\SQLEXPRESS;database=Northwind;Integrated Security=true<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">ConnectionString</span><span style="color:#0000ff;">&#62;</span>
  <span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Database</span><span style="color:#0000ff;">&#62;</span>
<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Metadata</span><span style="color:#0000ff;">&#62;</span></pre>
</pre>
<p>It describes the connection string to use to connect to example database. It use Northwind database, in SQL Server (full or express). If you don’t have Northwind, the creation scripts are in Sql folder.</p>
<p>To create the project and entities (the model to generate), run:</p>
<p><font face="Consolas">MakeModelFromDatabase.cmd</font></p>
<p>AjGenesis (compiled in Bin folder) begin to work:</p>
<p><img src="http://www.ajlopez.com/images/articles2/ajgenesisdb02.png" /> </p>
<p>The executed commad contains:</p>
<p><font face="Consolas">Bin\AjGenesis.Console Projects\Northwind\Metadata.xml Tasks\DatabaseProcess.ajg</font></p>
<p>This command loads Metadata.xml as model in memory, and executes the AjBasic task DatabaseProcess.ajg. This tasks use <a href="http://msdn.microsoft.com/en-us/library/ms186778.aspx" target="_blank">Information Schema views</a> to obtain information about database structure (using information schema views opens the possibility of database independence).</p>
<p>The task creates Projects\Northwind\Project.xml file:</p>
<pre>
<pre style="background-color:#ffffff;width:100%;font-family:consolas;font-size:12px;margin:0;"><span style="color:#0000ff;">&#60;?</span>xml version=&#34;1.0&#34; encoding=&#34;ISO-8859-1&#34; standalone=&#34;yes&#34;<span style="color:#0000ff;">?&#62;</span>
<span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Project</span><span style="color:#0000ff;">&#62;</span>
  <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Name</span><span style="color:#0000ff;">&#62;</span>Northwind<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Name</span><span style="color:#0000ff;">&#62;</span>
  <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Model</span><span style="color:#0000ff;">&#62;</span>
    <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Entities</span><span style="color:#0000ff;">&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Entity</span> <span style="color:#ff0000;">Source</span>=<span style="color:#0000ff;">&#34;Entities/Customer.xml&#34;</span><span style="color:#0000ff;">/&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Entity</span> <span style="color:#ff0000;">Source</span>=<span style="color:#0000ff;">&#34;Entities/Shipper.xml&#34;</span><span style="color:#0000ff;">/&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Entity</span> <span style="color:#ff0000;">Source</span>=<span style="color:#0000ff;">&#34;Entities/Supplier.xml&#34;</span><span style="color:#0000ff;">/&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Entity</span> <span style="color:#ff0000;">Source</span>=<span style="color:#0000ff;">&#34;Entities/Order.xml&#34;</span><span style="color:#0000ff;">/&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Entity</span> <span style="color:#ff0000;">Source</span>=<span style="color:#0000ff;">&#34;Entities/Product.xml&#34;</span><span style="color:#0000ff;">/&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Entity</span> <span style="color:#ff0000;">Source</span>=<span style="color:#0000ff;">&#34;Entities/OrderDetail.xml&#34;</span><span style="color:#0000ff;">/&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Entity</span> <span style="color:#ff0000;">Source</span>=<span style="color:#0000ff;">&#34;Entities/CustomerCustomerDemo.xml&#34;</span><span style="color:#0000ff;">/&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Entity</span> <span style="color:#ff0000;">Source</span>=<span style="color:#0000ff;">&#34;Entities/CustomerDemographic.xml&#34;</span><span style="color:#0000ff;">/&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Entity</span> <span style="color:#ff0000;">Source</span>=<span style="color:#0000ff;">&#34;Entities/Region.xml&#34;</span><span style="color:#0000ff;">/&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Entity</span> <span style="color:#ff0000;">Source</span>=<span style="color:#0000ff;">&#34;Entities/Territory.xml&#34;</span><span style="color:#0000ff;">/&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Entity</span> <span style="color:#ff0000;">Source</span>=<span style="color:#0000ff;">&#34;Entities/EmployeeTerritory.xml&#34;</span><span style="color:#0000ff;">/&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Entity</span> <span style="color:#ff0000;">Source</span>=<span style="color:#0000ff;">&#34;Entities/Employee.xml&#34;</span><span style="color:#0000ff;">/&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Entity</span> <span style="color:#ff0000;">Source</span>=<span style="color:#0000ff;">&#34;Entities/Category.xml&#34;</span><span style="color:#0000ff;">/&#62;</span>
    <span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Entities</span><span style="color:#0000ff;">&#62;</span>
  <span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Model</span><span style="color:#0000ff;">&#62;</span>
<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Project</span><span style="color:#0000ff;">&#62;</span>
</pre>
</pre>
<p>The project and entities are similar to the ones I used in <a href="http://ajlopez.wordpress.com/2007/11/12/application-generation-using-ajgenesis/" target="_blank">Application generationg using AjGenesis</a> (but there are not the same). Part of the generated file Projects\Northwind\Entities\Customer.xml:</p>
<pre>
<pre style="background-color:#ffffff;width:100%;font-family:consolas;font-size:12px;margin:0;"><span style="color:#0000ff;">&#60;?</span>xml version=&#34;1.0&#34; encoding=&#34;ISO-8859-1&#34; standalone=&#34;yes&#34;<span style="color:#0000ff;">?&#62;</span>
<span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Entity</span><span style="color:#0000ff;">&#62;</span>
  <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Name</span><span style="color:#0000ff;">&#62;</span>Customer<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Name</span><span style="color:#0000ff;">&#62;</span>
  <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Description</span><span style="color:#0000ff;">&#62;</span>Customer<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Description</span><span style="color:#0000ff;">&#62;</span>
  <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">SetName</span><span style="color:#0000ff;">&#62;</span>Customers<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Name</span><span style="color:#0000ff;">&#62;</span>
  <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Descriptor</span><span style="color:#0000ff;">&#62;</span>Customer<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Descriptor</span><span style="color:#0000ff;">&#62;</span>
  <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">SetDescriptor</span><span style="color:#0000ff;">&#62;</span>Customers<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">SetDescriptor</span><span style="color:#0000ff;">&#62;</span>
  <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">SqlCatalog</span><span style="color:#0000ff;">&#62;</span>Northwind<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">SqlCatalog</span><span style="color:#0000ff;">&#62;</span>
  <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">SqlSchema</span><span style="color:#0000ff;">&#62;</span>dbo<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">SqlSchema</span><span style="color:#0000ff;">&#62;</span>
  <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">SqlName</span><span style="color:#0000ff;">&#62;</span>Customers<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">SqlName</span><span style="color:#0000ff;">&#62;</span>
  <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Properties</span><span style="color:#0000ff;">&#62;</span>
    <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Property</span><span style="color:#0000ff;">&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Name</span><span style="color:#0000ff;">&#62;</span>CustomerID<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Name</span><span style="color:#0000ff;">&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Description</span><span style="color:#0000ff;">&#62;</span>CustomerID<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Description</span><span style="color:#0000ff;">&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">SqlName</span><span style="color:#0000ff;">&#62;</span>CustomerID<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">SqlName</span><span style="color:#0000ff;">&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">SqlLength</span><span style="color:#0000ff;">&#62;</span>5<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">SqlLength</span><span style="color:#0000ff;">&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">IsKey</span><span style="color:#0000ff;">&#62;</span>True<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">IsKey</span><span style="color:#0000ff;">&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">SqlType</span><span style="color:#0000ff;">&#62;</span>nchar<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">SqlType</span><span style="color:#0000ff;">&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">SystemType</span><span style="color:#0000ff;">&#62;</span>String<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">SystemType</span><span style="color:#0000ff;">&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">IsNullable</span><span style="color:#0000ff;">&#62;</span>False<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">IsNullable</span><span style="color:#0000ff;">&#62;</span>
    <span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Property</span><span style="color:#0000ff;">&#62;</span>
....
  <span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Properties</span><span style="color:#0000ff;">&#62;</span>
<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Entity</span><span style="color:#0000ff;">&#62;</span>
</pre>
</pre>
<p>The main logic resides in Tasks\DatabaseProcess.ajg, written in AjBasic dynamic language, fragment:</p>
<pre>
<pre style="background-color:#ffffff;width:100%;font-family:consolas;font-size:12px;margin:0;">cmd = <span style="color:#0000ff;">new</span> System.Data.SqlClient.SqlCommand()
cmd.Connection = conn
cmd.CommandText = &#34;<span style="color:#8b0000;">select * from Information_Schema.Tables where Table_Type = 'BASE TABLE'</span>&#34;
conn.Open()
PrintLine &#34;<span style="color:#8b0000;">Reader</span>&#34;
dr = cmd.ExecuteReader()
Tables = CreateList()
<span style="color:#0000ff;">while</span> dr.Read()
  PrintLine &#34;<span style="color:#8b0000;">Table </span>&#34; &#38; dr.Item(&#34;<span style="color:#8b0000;">Table_Name</span>&#34;) &#38; &#34;<span style="color:#8b0000;">: </span>&#34; &#38; dr.Item(&#34;<span style="color:#8b0000;">Table_Type</span>&#34;)
  Table = CreateObject()
  Table.SqlCatalog = dr.Item(&#34;<span style="color:#8b0000;">Table_Catalog</span>&#34;)
  Table.SqlSchema = dr.Item(&#34;<span style="color:#8b0000;">Table_Schema</span>&#34;)
  Table.SqlName = dr.Item(&#34;<span style="color:#8b0000;">Table_Name</span>&#34;)
  Table.Name = Table.SqlName.Replace(&#34;<span style="color:#8b0000;"> </span>&#34;,&#34;<span style="color:#8b0000;"></span>&#34;)

  <span style="color:#0000ff;">if</span> IsPlural(Table.Name) <span style="color:#0000ff;">then</span>
    Table.SetName = Table.Name
    Table.Name = ToSingular(Table.Name)
  <span style="color:#0000ff;">else</span>
    Table.SetName = ToPlural(Table.Name)
  <span style="color:#0000ff;">end</span> <span style="color:#0000ff;">if</span>

  Table.Descriptor = Table.Name
  Table.SetDescriptor = Table.SetName

  Table.Description = Table.Name

  Tables.Add(Table)
<span style="color:#0000ff;">end</span> <span style="color:#0000ff;">while</span>
dr.Close()</pre>
</pre>
<h3>Possible improvements</h3>
<p>This examples is a “proof of concept”. To be used in a more general way, it should be improved. Some points to work:</p>
<p>- Use the generated model to generate a working application, scaffolding or not.</p>
<p>- Support of more meta data obtained via Information Schema</p>
<p>- Try another databases, try a real example</p>
<p>- Relation treatment: detecting cascade and other actions</p>
<p>Another posts about initial models for AjGenesis:</p>
<p><a href="http://ajlopez.wordpress.com/2008/10/02/another-model-for-ajgenesis/" target="_blank">Another model for AjGenesis</a></p>
<p><a href="http://ajlopez.wordpress.com/2008/09/28/textual-model-for-code-generation-in-ajgenesis/" target="_blank">Textual model for code generation in AjGenesis</a></p>
<p><a href="http://ajlopez.wordpress.com/2008/04/23/ajgenesis-generating-the-model-from-assemblies/" target="_blank">AjGenesis: Generating the model from assemblies</a></p>
<p><a href="http://ajlopez.wordpress.com/2008/04/21/ajgenesis-generating-the-model-from-the-database/" target="_blank">AjGenesis: Generating the model from the database</a></p>
<p>Angel “Java” Lopez<br />
  <br /><a href="http://www.ajlopez.com">http://www.ajlopez.com</a></p>
<p><a href="http://twitter.com/ajlopez">http://twitter.com/ajlopez</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Generating code with AJGenesis using NHibernate hbm files]]></title>
<link>http://ajlopez.wordpress.com/2009/11/22/generating-code-with-ajgenesis-using-nhibernate-hbm-files/</link>
<pubDate>Sun, 22 Nov 2009 09:50:45 +0000</pubDate>
<dc:creator>ajlopez</dc:creator>
<guid>http://ajlopez.wordpress.com/2009/11/22/generating-code-with-ajgenesis-using-nhibernate-hbm-files/</guid>
<description><![CDATA[I was working on generating C# classes, using as starting point .hbm NHibernate mapping files. As us]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I was working on generating C# classes, using as starting point .hbm <a href="http://nhforge.org/" target="_blank">NHibernate</a> mapping files. As usual, I wrote an example with <a href="http://ajgenesis.codeplex.com" target="_blank">AjGenesis</a>, my open source code generation engine.</p>
<p>You can download a first example from my Skydrive:</p>
<p><a href="http://cid-9f903f3d6db0c176.skydrive.live.com/self.aspx/Examples/AjGenesis/NHibernateMappingExample01.zip" target="_blank">Examples &#62; AjGenesis &#62; NHibernateMappingExample01.zip</a></p>
<p>(the code is in the trunk, in <a href="http://ajgenesis.codeplex.com/sourcecontrol/changeset/view/61684?projectName=ajgenesis#" target="_blank">the current change set</a>, under examples\NHibernateMappinp:</p>
<p><img src="http://www.todocontenidos.com/images/articles/ajgenesisnh03.png" /> </p>
<p>but if you want to go directly to the example, the Skydrive download I mentioned has all you need to run this demo, including AjGenesis trunk code compiled to binaries).</p>
<p>After expanding the file, you have this content:</p>
<p>&#160;<img src="http://www.todocontenidos.com/images/articles/ajgenesisnh02.png" /> </p>
<p>To create C# classes, execute at command prompt:</p>
<pre>
<pre style="background-color:#ffffff;width:100%;font-family:consolas;font-size:10pt;margin:0;">GenerateClasses AjFirstExample
GenerateClasses AjTest</pre>
</pre>
<p>To create a .NET project with the .cs and .hbm files, run:</p>
<pre>
<pre style="background-color:#ffffff;width:100%;font-family:consolas;font-size:10pt;margin:0;">GenerateProject AjFirstExample
GenerateProject AjTest</pre>
</pre>
<p>The generated files are created under Build folder.</p>
<p>The two example projects are AjFirstExample, with two simple plain mappings, and AjTest, with a more interesing mapping, with bags and many to one relations.</p>
<p>Currently, each project is described by a simple Project.xml:</p>
<pre>
<pre style="background-color:#ffffff;width:100%;font-family:consolas;font-size:10pt;margin:0;"><span style="color:#0000ff;">&#60;</span><span style="color:#800000;">Project</span> <span style="color:#ff0000;">Name</span>=<span style="color:#0000ff;">&#34;AjTest&#34;</span><span style="color:#0000ff;">&#62;</span>
<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">Project</span><span style="color:#0000ff;">&#62;</span></pre>
</pre>
<p>This is one of the mapping files in Projects\AjTest\Mappings, Department.hbm:</p>
<pre>
<pre style="background-color:#ffffff;width:100%;font-family:consolas;font-size:10pt;margin:0;"><span style="color:#0000ff;">&#60;?</span>xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34; <span style="color:#0000ff;">?&#62;</span>
<span style="color:#0000ff;">&#60;</span><span style="color:#800000;">hibernate</span>-<span style="color:#ff0000;">mapping</span> <span style="color:#ff0000;">xmlns</span>=<span style="color:#0000ff;">&#34;urn:nhibernate-mapping-2.2&#34;</span>
  <span style="color:#ff0000;">assembly</span>=<span style="color:#0000ff;">&#34;AjTest.Entities&#34;</span>
  <span style="color:#ff0000;">namespace</span>=<span style="color:#0000ff;">&#34;AjTest.Entities&#34;</span>
  <span style="color:#0000ff;">&#62;</span>
  <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">class</span> <span style="color:#ff0000;">name</span>=<span style="color:#0000ff;">&#34;Department&#34;</span> <span style="color:#ff0000;">table</span>=<span style="color:#0000ff;">&#34;departments&#34;</span><span style="color:#0000ff;">&#62;</span>
    <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">id</span> <span style="color:#ff0000;">name</span>=<span style="color:#0000ff;">&#34;Id&#34;</span> <span style="color:#ff0000;">column</span>=<span style="color:#0000ff;">&#34;Id&#34;</span> <span style="color:#ff0000;">type</span>=<span style="color:#0000ff;">&#34;Int32&#34;</span><span style="color:#0000ff;">&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">generator</span> <span style="color:#ff0000;">class</span>=<span style="color:#0000ff;">&#34;native&#34;</span><span style="color:#0000ff;">/&#62;</span>
    <span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">id</span><span style="color:#0000ff;">&#62;</span>
    <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">property</span> <span style="color:#ff0000;">name</span>=<span style="color:#0000ff;">&#34;Description&#34;</span> <span style="color:#ff0000;">type</span>=<span style="color:#0000ff;">&#34;String&#34;</span><span style="color:#0000ff;">/&#62;</span>
    <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">bag</span> <span style="color:#ff0000;">name</span>=<span style="color:#0000ff;">&#34;Employees&#34;</span> <span style="color:#ff0000;">lazy</span>=<span style="color:#0000ff;">&#34;true&#34;</span> <span style="color:#ff0000;">inverse</span>=<span style="color:#0000ff;">&#34;true&#34;</span> <span style="color:#ff0000;">cascade</span>=<span style="color:#0000ff;">&#34;all&#34;</span><span style="color:#0000ff;">&#62;</span>
</pre>
<pre style="background-color:#ffffff;width:100%;font-family:consolas&#60;font-size:12px;margin:0;">      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">key</span> <span style="color:#ff0000;">column</span>=<span style="color:#0000ff;">&#34;IdDepartment&#34;</span><span style="color:#0000ff;">/&#62;</span>
      <span style="color:#0000ff;">&#60;</span><span style="color:#800000;">one</span>-<span style="color:#ff0000;">to</span>-<span style="color:#ff0000;">many</span> <span style="color:#ff0000;">class</span>=<span style="color:#0000ff;">&#34;AjTest.Entities.Employee, AjTest.Entities&#34;</span><span style="color:#0000ff;">/&#62;</span>
    <span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">bag</span><span style="color:#0000ff;">&#62;</span>
  <span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">class</span><span style="color:#0000ff;">&#62;</span>
<span style="color:#0000ff;">&#60;/</span><span style="color:#800000;">hibernate</span>-mapping<span style="color:#0000ff;">&#62;</span>
</pre>
</pre>
<p>This is the generated code for this mapping, Department.generated.cs:</p>
<pre>
<pre style="background-color:#ffffff;width:100%;font-family:consolas;font-size:10pt;margin:0;"><span style="color:#0000ff;">using</span> System;
<span style="color:#0000ff;">using</span> System.Collections.Generic;
<span style="color:#0000ff;">using</span> Iesi.Collections.Generic;
<span style="color:#0000ff;">namespace</span> AjTest.Entities
{
  <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> Department {
    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">int</span> Id { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }
    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">string</span> Description { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }
    <span style="color:#0000ff;">public</span> IList&#60;Employee&#62; Employees { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }
    <span style="color:#0000ff;">public</span> Department()
    {
      <span style="color:#0000ff;">this</span>.Employees = <span style="color:#0000ff;">new</span> List&#60;Employee&#62;();
    }
  }
}
</pre>
</pre>
<p>Lets take a look to generation process. This is GenerateProject.cmd:</p>
<pre>
<pre style="background-color:#ffffff;width:100%;font-family:consolas;font-size:10pt;margin:0;">@echo off
<span style="color:#0000ff;">set</span> ProjectName=%1%
<span style="color:#0000ff;">if</span> &#34;<span style="color:#8b0000;">%1%</span>&#34;==&#34;<span style="color:#8b0000;"></span>&#34; <span style="color:#0000ff;">set</span> ProjectName=AjFirstExample
Bin\AjGenesis.Console.exe Projects\%ProjectName%\Project.xml Tasks\AddMappings.ajg Tasks\BuildCSharp.ajg
xcopy Libraries\*.* Build\%ProjectName%\CSharp\Src\Libraries /Y /Q</pre>
</pre>
<p>The main line is the one containing AjGenesis.Console.exe invocation. Project.xml is loaded in memory. The AddMapping.ajg task is loaded and executed, and then, BuildCSharp.ajg task is processed. AddMapping.ajg code (written in AjBasic, the dinamic language currently used by AjGenesis):</p>
<pre>
<pre style="background-color:#ffffff;width:100%;font-family:consolas;font-size:10pt;margin:0;"><span style="color:#008000;">' Add mappings from directory if not specified in Project model</span>
Include(&#34;<span style="color:#8b0000;">Utilities/Utilities.tpl</span>&#34;)
<span style="color:#0000ff;">if</span> <span style="color:#0000ff;">not</span> Project.Mappings <span style="color:#0000ff;">then</span>
  Project.Mappings = CreateList()

  di = <span style="color:#0000ff;">new</span> System.IO.DirectoryInfo(&#34;<span style="color:#8b0000;">Projects/${Project.Name}/Mappings</span>&#34;)

  <span style="color:#0000ff;">for</span> <span style="color:#0000ff;">each</span> fi <span style="color:#0000ff;">in</span> di.GetFiles(&#34;<span style="color:#8b0000;">*.hbm.xml</span>&#34;)
    filename = fi.Name
    Project.Mappings.Add(filename.Substring(0, filename.Length - 8))
  <span style="color:#0000ff;">end</span> <span style="color:#0000ff;">for</span>
<span style="color:#0000ff;">end</span> <span style="color:#0000ff;">if</span>
</pre>
</pre>
<p>It adds the name of mapping files contained in the Mapping folder of the project. A more interesing task is GenerateCSharp.ajg. First, it loads the NHibernate library to use its hbm parser:</p>
<pre>
<pre style="background-color:#ffffff;width:100%;font-family:consolas;font-size:10pt;margin:0;">include &#34;<span style="color:#8b0000;">Utilities/Utilities.tpl</span>&#34;
include &#34;<span style="color:#8b0000;">Utilities/FileUtilities.tpl</span>&#34;
include &#34;<span style="color:#8b0000;">Utilities/TypeUtilities.tpl</span>&#34;
Include(&#34;<span style="color:#8b0000;">Utilities/NHibernateUtilities.tpl</span>&#34;)
include &#34;<span style="color:#8b0000;">Templates/CSharp/UtilitiesCs.tpl</span>&#34;
include &#34;<span style="color:#8b0000;">Templates/CSharp/CSharpFunctions.tpl</span>&#34;
AssemblyManager.LoadFrom(&#34;<span style="color:#8b0000;">Libraries/NHibernate.dll</span>&#34;)
parser = <span style="color:#0000ff;">new</span> NHibernate.Cfg.MappingSchema.MappingDocumentParser()
</pre>
</pre>
<p>Then, it creates the solution and project objects:</p>
<pre>
<pre style="background-color:#ffffff;width:100%;font-family:consolas;font-size:10pt;margin:0;"><span style="color:#0000ff;">if</span> <span style="color:#0000ff;">not</span> Project.BuildDir <span style="color:#0000ff;">then</span>
  Project.BuildDir = &#34;<span style="color:#8b0000;">Build/${Project.Name}/CSharp</span>&#34;
<span style="color:#0000ff;">end</span> <span style="color:#0000ff;">if</span>
message &#34;<span style="color:#8b0000;">Creating Directories...</span>&#34;
FileManager.CreateDirectory(Project.BuildDir)
FileManager.CreateDirectory(&#34;<span style="color:#8b0000;">${Project.BuildDir}/Sql</span>&#34;)
FileManager.CreateDirectory(&#34;<span style="color:#8b0000;">${Project.BuildDir}/Src</span>&#34;)
FileManager.CreateDirectory(&#34;<span style="color:#8b0000;">${Project.BuildDir}/Src/Libraries</span>&#34;)
message &#34;<span style="color:#8b0000;">Defining Solution and Projects...</span>&#34;
Project.Solution = CreateObject()
Project.Solution.Guid = &#34;<span style="color:#8b0000;">FAE04EC0-301F-11D3-BF4B-00C04F79EFBC</span>&#34;
Project.Solution.Projects = CreateList()
message &#34;<span style="color:#8b0000;">Defining Entities Project...</span>&#34;
PrjEntities = CreateObject()
PrjEntities.Includes = CreateList()
PrjEntities.Guid = CreateGuid()
PrjEntities.COMGuid = CreateGuid()
Project.Solution.Projects.Add(PrjEntities)
Project.Entities = CreateList()
</pre>
</pre>
<p>Then, it iterates on each hbm file, to get information about the entities to generate:</p>
<pre>
<pre style="background-color:#ffffff;width:100%;font-family:consolas;font-size:10pt;margin:0;"><span style="color:#0000ff;">for</span> <span style="color:#0000ff;">each</span> MappingName <span style="color:#0000ff;">in</span> Project.Mappings
  filename = &#34;<span style="color:#8b0000;">Projects/${Project.Name}/Mappings/${MappingName}.hbm.xml</span>&#34;
  mapping = parser.Parse(OpenAsStream(filename))

  <span style="color:#0000ff;">for</span> <span style="color:#0000ff;">each</span> hbmclass <span style="color:#0000ff;">in</span> mapping.Items where IsType(hbmclass, &#34;<span style="color:#8b0000;">HbmClass</span>&#34;)
    Entity = CreateObject()

    Project.Entities.Add(Entity)

    Entity.ClassName = hbmclass.name
    Entity.<span style="color:#0000ff;">Namespace</span> = mapping.<span style="color:#0000ff;">namespace</span>

    <span style="color:#008000;">' Namespace as default project name for Entities Project</span>
    <span style="color:#0000ff;">if</span> <span style="color:#0000ff;">not</span> PrjEntities.Name <span style="color:#0000ff;">then</span>
      PrjEntities.Name = mapping.<span style="color:#0000ff;">namespace</span>
      PrjEntities.Directory = &#34;<span style="color:#8b0000;">${Project.BuildDir}/Src/${PrjEntities.Name}</span>&#34;
      FileManager.CreateDirectory(PrjEntities.Directory)
    <span style="color:#0000ff;">end</span> <span style="color:#0000ff;">if</span>

    Entity.Properties = CreateList()

    <span style="color:#0000ff;">if</span> hbmclass.Id <span style="color:#0000ff;">then</span>
      <span style="color:#0000ff;">Property</span> = CreateObject()
      <span style="color:#0000ff;">Property</span>.Name = hbmclass.Id.name
      <span style="color:#0000ff;">Property</span>.Type = HbmTypeToCSharp(hbmclass.Id.type1, Entity.<span style="color:#0000ff;">Namespace</span>)
      Entity.Properties.Add(<span style="color:#0000ff;">Property</span>)
    <span style="color:#0000ff;">end</span> <span style="color:#0000ff;">if</span>

    <span style="color:#0000ff;">for</span> <span style="color:#0000ff;">each</span> item <span style="color:#0000ff;">in</span> hbmclass.Items
      <span style="color:#0000ff;">if</span> IsType(item, &#34;<span style="color:#8b0000;">HbmProperty</span>&#34;) <span style="color:#0000ff;">then</span>
        <span style="color:#0000ff;">Property</span> = CreateObject()
        <span style="color:#0000ff;">Property</span>.Name = item.name
        <span style="color:#0000ff;">Property</span>.Type = HbmTypeToCSharp(item.type1, Entity.<span style="color:#0000ff;">Namespace</span>)
        Entity.Properties.Add(<span style="color:#0000ff;">Property</span>)
      <span style="color:#0000ff;">end</span> <span style="color:#0000ff;">if</span>

      <span style="color:#0000ff;">if</span> IsType(item, &#34;<span style="color:#8b0000;">HbmManyToOne</span>&#34;) <span style="color:#0000ff;">then</span>
        <span style="color:#0000ff;">Property</span> = CreateObject()
        <span style="color:#0000ff;">Property</span>.Name = item.name
        <span style="color:#0000ff;">Property</span>.Type = HbmTypeToCSharp(item.<span style="color:#0000ff;">class</span>, Entity.<span style="color:#0000ff;">Namespace</span>)
        Entity.Properties.Add(<span style="color:#0000ff;">Property</span>)
      <span style="color:#0000ff;">end</span> <span style="color:#0000ff;">if</span>
      <span style="color:#0000ff;">if</span> IsType(item, &#34;<span style="color:#8b0000;">HbmSet</span>&#34;) <span style="color:#0000ff;">then</span>
        <span style="color:#0000ff;">Property</span> = CreateObject()
        <span style="color:#0000ff;">Property</span>.Name = item.name
        <span style="color:#0000ff;">Property</span>.IsSet = <span style="color:#0000ff;">true</span>
        <span style="color:#0000ff;">Property</span>.Type = HbmTypeToCSharp(item.Item.<span style="color:#0000ff;">class</span>, Entity.<span style="color:#0000ff;">Namespace</span>)
        Entity.Properties.Add(<span style="color:#0000ff;">Property</span>)
      <span style="color:#0000ff;">end</span> <span style="color:#0000ff;">if</span>
      <span style="color:#0000ff;">if</span> IsType(item, &#34;<span style="color:#8b0000;">HbmBag</span>&#34;) <span style="color:#0000ff;">then</span>
        <span style="color:#0000ff;">Property</span> = CreateObject()
        <span style="color:#0000ff;">Property</span>.Name = item.name
        <span style="color:#0000ff;">Property</span>.IsList = <span style="color:#0000ff;">true</span>
        <span style="color:#0000ff;">Property</span>.Type = HbmTypeToCSharp(item.Item.<span style="color:#0000ff;">class</span>, Entity.<span style="color:#0000ff;">Namespace</span>)
        Entity.Properties.Add(<span style="color:#0000ff;">Property</span>)
      <span style="color:#0000ff;">end</span> <span style="color:#0000ff;">if</span>
    <span style="color:#0000ff;">end</span> <span style="color:#0000ff;">for</span>
  <span style="color:#0000ff;">end</span> <span style="color:#0000ff;">for</span>
<span style="color:#0000ff;">end</span> <span style="color:#0000ff;">for</span>
</pre>
</pre>
<p>You can extend the capabilities, processing more tags (I should write an example using Meta tags), and detecting more NHibernate mapping idioms. Now, the task generates the code:</p>
<pre>
<pre style="background-color:#ffffff;width:100%;font-family:consolas;font-size:10pt;margin:0;"><span style="color:#0000ff;">for</span> <span style="color:#0000ff;">each</span> Entity <span style="color:#0000ff;">in</span> Project.Entities
  TransformerManager.Transform(&#34;<span style="color:#8b0000;">Templates/CSharp/Entity.tpl</span>&#34;, &#34;<span style="color:#8b0000;">${PrjEntities.Directory}/${Entity.ClassName}.generated.cs</span>&#34;, Environment)
  PrjEntities.Includes.Add(CreateFileCs(&#34;<span style="color:#8b0000;">${Entity.ClassName}.generated</span>&#34;))
<span style="color:#0000ff;">end</span> <span style="color:#0000ff;">for</span>
</pre>
</pre>
<p>The tasks not only generates the .cs files, but it creates a solution and a C# project, copying and embedding the original mapping files:</p>
<pre>
<pre style="background-color:#ffffff;width:100%;font-family:consolas;font-size:10pt;margin:0;"><span style="color:#0000ff;">for</span> <span style="color:#0000ff;">each</span> MappingName <span style="color:#0000ff;">in</span> Project.Mappings
  filename = &#34;<span style="color:#8b0000;">Projects/${Project.Name}/Mappings/${MappingName}.hbm.xml</span>&#34;
  targetfilename = &#34;<span style="color:#8b0000;">${PrjEntities.Directory}/${MappingName}.hbm.xml</span>&#34;
  System.IO.File.Copy(filename, targetfilename, <span style="color:#0000ff;">true</span>)
  PrjEntities.Includes.Add(CreateFileType(MappingName,&#34;<span style="color:#8b0000;">hbm.xml</span>&#34;))
<span style="color:#0000ff;">end</span> <span style="color:#0000ff;">for</span>
<span style="color:#0000ff;">for</span> <span style="color:#0000ff;">each</span> CsProject <span style="color:#0000ff;">in</span> Project.Solution.Projects where CsProject.ProjectType&#60;&#62;&#34;<span style="color:#8b0000;">Web</span>&#34;
  FileManager.CreateDirectory(CsProject.Directory)
  FileManager.CreateDirectory(CsProject.Directory &#38; &#34;<span style="color:#8b0000;">/Properties</span>&#34;)
  TransformerManager.Transform(&#34;<span style="color:#8b0000;">Templates/CSharp/CsProject.tpl</span>&#34;, &#34;<span style="color:#8b0000;">${CsProject.Directory}/${CsProject.Name}.csproj</span>&#34;, Environment)
  TransformerManager.Transform(&#34;<span style="color:#8b0000;">Templates/CSharp/AssemblyInfoCs.tpl</span>&#34;, &#34;<span style="color:#8b0000;">${CsProject.Directory}/Properties/AssemblyInfo.cs</span>&#34;, Environment)
<span style="color:#0000ff;">end</span> <span style="color:#0000ff;">for</span>
TransformerManager.Transform(&#34;<span style="color:#8b0000;">Templates/Solution.tpl</span>&#34;, &#34;<span style="color:#8b0000;">${Project.BuildDir}/Src/${Project.Name}.sln</span>&#34;, Environment)
</pre>
</pre>
<p>This is the generated solution:</p>
<p><img src="http://www.todocontenidos.com/images/articles/ajgenesisnh01.png" /> </p>
<h3>Next steps</h3>
<p>I should work in these point:</p>
<p>- Generate a more complete solution (with NHibernate infrastructure, Web Presentation, etc…) as in others AjGenesis examples. </p>
<p>- Support more NHibernate mapping options</p>
<p>- Use meta tags</p>
<p>But now, you are able to play with this example. You can change the templates to generate more artifacts, as Visual Basic .NET source files.</p>
<p>Thanks to <a href="http://twitter.com/fabiomaulo" target="_blank">@fabiomaulo</a> for pointing me to the NHibernate hbm parser capabilities!</p>
<p>Angel “Java” Lopez<br />
  <br /><a href="http://www.ajlopez.com">http://www.ajlopez.com</a> </p>
<p><a href="http://twitter.com/ajlopez">http://twitter.com/ajlopez</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[dbscript Videos]]></title>
<link>http://devio.wordpress.com/2009/11/21/dbscript-videos/</link>
<pubDate>Sat, 21 Nov 2009 11:10:50 +0000</pubDate>
<dc:creator>devio</dc:creator>
<guid>http://devio.wordpress.com/2009/11/21/dbscript-videos/</guid>
<description><![CDATA[I created a couple of introductory videos describing dbscript covering topics previously handled on ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I created a couple of introductory videos describing <a href="http://www.devio.at/index.php/dbscript" target="_blank">dbscript</a> covering topics previously handled on this blog or in the online help:<img src="http://static.devio.at/t.gif?http://devio.wordpress.com/2009/11/21/dbscript-videos" alt="" width="1" height="1" /></p>
<ul>
<li><a href="http://dbshelp.devio.at/index.php/Installation" target="_blank">Installation</a></li>
<li>Database schema import from SQL Server database</li>
<li>Data Diagram generation (<a href="http://devio.wordpress.com/2009/03/23/new-features-in-dbscript-095/" target="_blank">png</a>, <a href="http://devio.wordpress.com/2009/09/27/creating-dia-data-diagrams-from-database-schema/" target="_blank">Dia</a>)</li>
<li><a href="http://devio.wordpress.com/2009/02/03/generating-html-documentation-of-ms-sql-database/" target="_blank">Generating HTML documentation</a></li>
</ul>
<p>The videos have been created using <a href="http://camstudio.org/" target="_blank">CamStudio</a> (screen recorder) and <a href="http://www.virtualdub.org/" target="_blank">VirtualDub</a> (avi editor) and <a href="http://www.google.at/search?q=ffmpeg+windows" target="_blank">ffmpeg</a> (avi to flv converter). <a href="http://flowplayer.org/" target="_blank">FlowPlayer</a> is embedded by a <a href="http://extensions.joomla.org/extensions/multimedia/video-players-a-gallery/7377" target="_blank">Joomla plug-in</a>.</p>
<p>The videos can be watched <a href="http://www.devio.at/index.php/videos" target="_blank">here</a>. dbscript is available for <a href="http://gforge.devio.at/projects/dbscript/" target="_blank">download here</a>.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[the status of .netSavant...]]></title>
<link>http://hurtsmybrains.wordpress.com/2009/11/11/the-status-of-netsavant/</link>
<pubDate>Wed, 11 Nov 2009 22:40:08 +0000</pubDate>
<dc:creator>Joshua Gall</dc:creator>
<guid>http://hurtsmybrains.wordpress.com/2009/11/11/the-status-of-netsavant/</guid>
<description><![CDATA[I have this awesome little ADO.NET code generator called .netSavant.  It analyzes your stored proced]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I have this awesome little ADO.NET code generator called .netSavant.  It analyzes your stored procedures and generates an optimized wrapper class that encapsulates the logic for execution.  After using it myself for quite some time, I thought, oddly, that I could make a little extra cash from the endeavor.  Heh, sadly I was wrong.  Dispite a lot of interest, few people were interested in paying $50 for a visual studio addin that saved a LOT of time and buggy code.  Wierd, but whatever.</p>
<p>So, with mixed feelings I killed the project.  It simply cost too much money to maintain the website and merchant account for a product that only sold a handful of licenses over the 18-24 months.</p>
<p>I&#8217;m left wondering what to do with the project.  There are a few options:</p>
<ol>
<li>Create a codeplex project</li>
<li>Host the source code myself</li>
<li>Release the addin as freeware (no source code)</li>
<li>Release the addin as freeware with sponsorship (uhg, gross right?) (no source code)</li>
<li>Leave the project inactive and move on to other exciting technologies</li>
</ol>
<p>I&#8217;m wondering if I really want to spend more effort supporting the project as a whole, though with so much time invested, its hard to walk away from it.  Part of me would like to see more people use .netSavant, if only to justify the time I spent creating it.  I&#8217;d also like the challenge of updating some of the methodology used to generate the source code, and possibly provide some extensibility points to enhance the analysis features that it supports.</p>
<p>Perhaps some day .netSavant will be resurrected in a better form.  Until that time, thanks for your interest and support.</p>
<p>Joshua</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Android FastCoding]]></title>
<link>http://mobilebytes.wordpress.com/2009/10/30/android-fastcoding/</link>
<pubDate>Fri, 30 Oct 2009 19:06:18 +0000</pubDate>
<dc:creator>sharemefg</dc:creator>
<guid>http://mobilebytes.wordpress.com/2009/10/30/android-fastcoding/</guid>
<description><![CDATA[Now that with the release of Android 2.0 we will be targeting different versions for a bit its time ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Now that with the release of Android 2.0 we will be targeting different versions for a bit its time to embrace code generation. This is the code generation I am building up:</p>
<p><a href="http://mobilebytes.wordpress.com/files/2009/10/glrenderer-java-eclipse.png"><img class="alignnone size-medium wp-image-469" title="GLRenderer.java - Eclipse" src="http://mobilebytes.wordpress.com/files/2009/10/glrenderer-java-eclipse.png?w=300" alt="GLRenderer.java - Eclipse" width="300" height="195" /></a></p>
<p>What you are seeing is my use of <a href="http://github.com/srizzo/code2code">Code2Code plugin</a> to generate a base of generators for class templates. You do not have to know that much template engine stuff as it auto generates most o fit right from the java  class file you create.  Than to enable copy the generators you need ot project root and change one line of configuration and you all set to go.</p>
<div class="zemanta-pixie" style="margin-top:10px;height:15px;"><a class="zemanta-pixie-a" title="Reblog this post [with Zemanta]" href="http://reblog.zemanta.com/zemified/33b8be02-6811-45f5-a450-668a560ee3ea/"><img class="zemanta-pixie-img" style="border:medium none;float:right;" src="http://img.zemanta.com/reblog_e.png?x-id=33b8be02-6811-45f5-a450-668a560ee3ea" alt="Reblog this post [with Zemanta]" /></a></div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[T4 Preprocessed Text Templates in Visual Studio 2010]]></title>
<link>http://karlshifflett.wordpress.com/2009/10/30/t4-preprocessed-text-templates-in-visual-studio-2010/</link>
<pubDate>Fri, 30 Oct 2009 16:23:23 +0000</pubDate>
<dc:creator>Karl Shifflett</dc:creator>
<guid>http://karlshifflett.wordpress.com/2009/10/30/t4-preprocessed-text-templates-in-visual-studio-2010/</guid>
<description><![CDATA[The best kept secret in Redmond, WA are the new T4 Preprocess Text Templates that shipped in Visual ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>The best kept secret in Redmond, WA are the new T4 Preprocess Text Templates that shipped in Visual Studio 2010 Beta1 and Beta2.&#160; In just a few minutes you’ll be in the know and using them.</p>
<h4>Background – Condensed </h4>
<p><strong>T4</strong> = text template transformation toolkit</p>
<p>T4 templates have been available since Visual Studio 2005 and are part of DSL (Domain Specific Languages) documentation.</p>
<p>In Visual Studio 2010 the templates are MUCH easier to use because they are preprocessed.&#160; When you save your T4 template, it is compiled.&#160; The T4 template is now “processed” at compile time.&#160; This was not the case in previous releases. </p>
<p>Your compiled template is just another type in an assembly that you can now instantiate and call its single method, TransformText.&#160; The only run-time requirement to use T4 templates is the .NET 2.0 Framework. </p>
<h4>Prerequisites</h4>
<ul>
<li>Visual Studio 2010 </li>
<li>T4 Editor Plug In&#160;
<ul>
<li>Visual Studio 2010 does not provide any editing assistance when editing T4 templates (.tt files).&#160; You can search the Internet for T4 Editor and you’ll find some information and products. </li>
<li>I’m currently using the Tangible T4 Editor (free) that you can get on the Visual Studio Gallery here:&#160;
<ul>
<li><a href="http://visualstudiogallery.msdn.microsoft.com/en-us/60297607-5fd4-4da4-97e1-3715e90c1a23" target="_blank">http://visualstudiogallery.msdn.microsoft.com/en-us/60297607-5fd4-4da4-97e1-3715e90c1a23</a> </li>
<li>The editor is an Alpha version, has a few limitations but I was able to author the below template in a few minutes. </li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Our Scenario</h4>
<p>We have been tasked with creating some code that we can pass data fields to and that code will create a VB.NET property.&#160; This code will be part of a larger program that is fed information and creates class files.</p>
<p>Before T4 Preprocessed templates we had several options available to us.&#160; Write code to spit out the required property, buy a 3rd party product, use CodeDom, etc.</p>
<p>Since we just installed Visual Studio 2010 Beta2, we are going for the productive, inexpensive, simple and out of the box solution, T4 Preprocessed Text Template.</p>
<h4>Our Test Bench</h4>
<p>This simple application simulates the data harness that will ultimately feed our T4 template and consume its output.&#160; Set a few data fields and press Generate Code.</p>
<p><a href="http://karlshifflett.files.wordpress.com/2009/10/demoapplicaiton.png"><img style="display:inline;border-width:0;" title="demoApplicaiton" border="0" alt="demoApplicaiton" src="http://karlshifflett.files.wordpress.com/2009/10/demoapplicaiton_thumb.png?w=510&#038;h=572" width="510" height="572" /></a></p>
<h4>Code Generation – It’s all about the data</h4>
<p>Code generation requires metadata to drive the output.&#160; With the new T4 templates, getting metadata into your T4 template is a simple matter of a partial class.&#160; The members in the partial class are available at design time and run-time.&#160; I know this seems so simple, but T4 did not always work this way.&#160; Now you have full design time strong typing and instant compile time verification of your template and code.</p>
<p>To keep this example as simple as possible, I’ve exposed the metadata directly as properties and passed values for them in the constructor of our Partial Class PropertyTemplate.&#160; For simple scenarios this totally fine.&#160; For a larger or multi-language code generation applications, a better solution is to expose the metadata through an Interface.&#160; The Interface type can contain metadata and helper methods that can be used in your T4 template.</p>
<p><a href="http://msmvps.com/blogs/kathleen/" target="_blank">Kathleen Dollard</a> and I have spoken a good bit about this and think using Interfaces for metadata and helper methods makes the most sense.&#160; I’m sure Kathleen will write more on this subject and I know I will.</p>
<p>In the below T4TemplateLibrary project you can see how I’ve set up the project.&#160; I had to turn on “Show All Files” to see the hidden file, “PropertyTemplate.vb” below the “PropertyTemplate.tt” file. </p>
<blockquote><p>Open the hidden “PropertyTemplate.vb” file up and you will see the type of code you and I used to have to write to generate code.&#160; Now T4 does it for us!</p>
</blockquote>
<p><a href="http://karlshifflett.files.wordpress.com/2009/10/t4project.png"><img style="display:inline;border-width:0;" title="T4Project" border="0" alt="T4Project" src="http://karlshifflett.files.wordpress.com/2009/10/t4project_thumb.png?w=244&#038;h=211" width="244" height="211" /></a></p>
<p>The below partial class is overly simple and exposes metadata that will be consumed by the T4 template.</p>
<div class="code">
<pre><span style="color:blue;">Namespace My</span>.Templates

  <span style="color:blue;">Partial Public Class </span><span style="color:#2b91af;">PropertyTemplate

    </span><span style="color:blue;">Public Property </span>PropertyName <span style="color:blue;">As String </span>= <span style="color:blue;">String</span>.Empty
    <span style="color:blue;">Public Property </span>BackingField <span style="color:blue;">As String </span>= <span style="color:blue;">String</span>.Empty
    <span style="color:blue;">Public Property </span>TypeName <span style="color:blue;">As String </span>= <span style="color:blue;">String</span>.Empty
    <span style="color:blue;">Public Property </span>IsShared <span style="color:blue;">As Boolean </span>= <span style="color:blue;">False
    Public Property </span>RaisePropertyChangedMethodName <span style="color:blue;">As String </span>= <span style="color:blue;">String</span>.Empty
    <span style="color:blue;">Public Property </span>IsReadOnly <span style="color:blue;">As Boolean </span>= <span style="color:blue;">False
    Public Property </span>Scope <span style="color:blue;">As String </span>= <span style="color:blue;">String</span>.Empty
    <span style="color:blue;">Public Property </span>IsSetterPrivate <span style="color:blue;">As Boolean </span>= <span style="color:blue;">False

    Public Sub New</span>(<span style="color:blue;">ByVal </span>strScope <span style="color:blue;">As String</span>, <span style="color:blue;">ByVal </span>bolIsShared <span style="color:blue;">As Boolean</span>,
                   <span style="color:blue;">ByVal </span>bolIsReadOnly <span style="color:blue;">As Boolean</span>, <span style="color:blue;">ByVal </span>bolIsSetterPrivate <span style="color:blue;">As Boolean</span>,
                   <span style="color:blue;">ByVal </span>strPropertyName <span style="color:blue;">As String</span>, <span style="color:blue;">ByVal </span>strBackingField <span style="color:blue;">As String</span>,
                   <span style="color:blue;">ByVal </span>strTypeName <span style="color:blue;">As String</span>, <span style="color:blue;">ByVal </span>strRaisePropertyChangedMethodName <span style="color:blue;">As String</span>)
      <span style="color:blue;">Me</span>.Scope = strScope
      <span style="color:blue;">Me</span>.IsShared = bolIsShared
      <span style="color:blue;">Me</span>.IsReadOnly = bolIsReadOnly
      <span style="color:blue;">Me</span>.IsSetterPrivate = bolIsSetterPrivate
      <span style="color:blue;">Me</span>.PropertyName = strPropertyName
      <span style="color:blue;">Me</span>.BackingField = strBackingField
      <span style="color:blue;">Me</span>.TypeName = strTypeName
      <span style="color:blue;">Me</span>.RaisePropertyChangedMethodName = strRaisePropertyChangedMethodName
    <span style="color:blue;">End Sub

  End Class

End Namespace
</span></pre>
</div>
<h4>T4 Template</h4>
<p>To add a T4 template to your project, select Add New Item, then type “preprocessed” in the search box.&#160; Select the Preprocess Text Template.</p>
<p>If you used classic ASP, then T4 template editing is a skill you already have.&#160; In classic ASP we used &#60;% and &#60;%=.&#160; In T4 we use &#60;# and &#60;#=.&#160; The reason for this change is so that T4 can be used to generate classic ASP and ASP.NET code.&#160; If you didn’t have the joy of shipping classic ASP web sites, no worries.&#160; 15 minutes of trail and error and you’ll be fully qualified.</p>
<p>The below image shows the free Tangible T4 Editor Plug-In IntelliSense in action.&#160; It provides IntelliSense for T4 directives and template specific constructs like &#60;#.&#160; It also colorizes the template code.&#160; Colorizing makes editing the template much easier too.&#160; One current limitation is that its IntelliSense engine does list member properties defined in the partial class for the template.</p>
<p><a href="http://karlshifflett.files.wordpress.com/2009/10/t4intellisense.png"><img style="display:inline;border-width:0;" title="T4IntelliSense" border="0" alt="T4IntelliSense" src="http://karlshifflett.files.wordpress.com/2009/10/t4intellisense_thumb.png?w=553&#038;h=263" width="553" height="263" /></a>&#160;</p>
<p>The below code block is the T4 template.&#160; It has a language directive at the top followed by static text and code blocks.</p>
<div class="code">
<pre style="overflow:auto;"><span style="color:black;">&#60;#@ </span><span style="color:brown;">template </span><span style="color:red;">language</span><span style="color:black;">=&#34;</span><span style="color:blue;">VB</span><span style="color:black;">&#34; #&#62;

&#60;#= </span><span style="color:blue;">Me</span><span style="color:black;">.Scope #&#62;&#60;#= </span><span style="color:blue;">IIF</span><span style="color:black;">(</span><span style="color:blue;">Me</span><span style="color:black;">.IsShared, </span><span style="color:maroon;">&#34; Shared&#34;</span><span style="color:black;">,</span><span style="color:maroon;">&#34;&#34;</span><span style="color:black;">) #&#62;&#60;#= </span><span style="color:blue;">IIF</span><span style="color:black;">(</span><span style="color:blue;">Me</span><span style="color:black;">.IsReadOnly, </span><span style="color:maroon;">&#34; ReadOnly&#34;</span><span style="color:black;">, </span><span style="color:maroon;">&#34;&#34;</span><span style="color:black;">) #&#62; Property &#60;#= </span><span style="color:blue;">Me</span><span style="color:black;">.PropertyName #&#62; As &#60;#= </span><span style="color:blue;">Me</span><span style="color:black;">.TypeName #&#62;
    Get
        Return &#60;#= </span><span style="color:blue;">Me</span><span style="color:black;">.BackingField #&#62;
    End Get
&#60;# </span><span style="color:blue;">If Not Me</span><span style="color:black;">.IsReadOnly </span><span style="color:blue;">Then </span><span style="color:black;">#&#62;
    &#60;#= </span><span style="color:blue;">IIF</span><span style="color:black;">(</span><span style="color:blue;">Me</span><span style="color:black;">.IsSetterPrivate, </span><span style="color:maroon;">&#34; Private &#34;</span><span style="color:black;">,</span><span style="color:maroon;">&#34;&#34;</span><span style="color:black;">) #&#62;Set(ByVal value As &#60;#= </span><span style="color:blue;">Me</span><span style="color:black;">.TypeName #&#62;)
&#60;# </span><span style="color:blue;">If String</span><span style="color:black;">.IsNullOrEmpty(</span><span style="color:blue;">Me</span><span style="color:black;">.RaisePropertyChangedMethodName) </span><span style="color:blue;">Then </span><span style="color:black;">#&#62;
        &#60;#= </span><span style="color:blue;">Me</span><span style="color:black;">.BackingField #&#62; = value
&#60;# </span><span style="color:blue;">Else </span><span style="color:black;">#&#62;
        &#60;#= </span><span style="color:blue;">Me</span><span style="color:black;">.BackingField #&#62; = value
        &#60;#= </span><span style="color:blue;">String</span><span style="color:black;">.Format(</span><span style="color:maroon;">&#34;{0}(&#34;&#34;{1}&#34;&#34;)&#34;</span><span style="color:black;">, </span><span style="color:blue;">Me</span><span style="color:black;">.RaisePropertyChangedMethodName, </span><span style="color:blue;">Me</span><span style="color:black;">.PropertyName) #&#62;
&#60;# </span><span style="color:blue;">End If </span><span style="color:black;">#&#62;
    End Set
&#60;# </span><span style="color:blue;">End If </span><span style="color:black;">#&#62;
End Property</span></pre>
</div>
<p>&#60;#=&#160; is the same as the ASP Response.Write.&#160; It writes the result of the expression into the template.&#160; For example, if the Scope is Public, &#60;#= Me.Scope #&#62; would yield Public when the template is transformed at run-time.</p>
<p>&#60;# is the beginning of a code block.&#160; Notice how the IsReadOnly property is tested.&#160; Basic on the result, an entire block of code can either run or be by-passed.&#160; This feature is so cool when you bring loops from LINQ queries into the picture.</p>
<p>One thing you’ll notice is that all the code blocks are left justified.&#160; Yes, this makes reading the template a little harder.&#160; However, if you don’t do this, the resulting code will be indented the same amount as the code block indentation.</p>
<p>So what I do when editing my templates is to indent everything to make it easier to edit the template.&#160; When I”m done, I go back and move the code to the left.</p>
<h4>Run-Time Rendering of T4 Templates</h4>
<div class="code">
<pre class="code"><span style="color:blue;">Dim </span>t <span style="color:blue;">As New </span><span style="color:#2b91af;">PropertyTemplate</span>(
    <span style="color:blue;">Me</span>.cboScope.SelectedItem.ToString,
    <span style="color:blue;">Me</span>.chkIsShared.IsChecked.Value,
    <span style="color:blue;">Me</span>.chkIsReadOnly.IsChecked.Value,
    <span style="color:blue;">Me</span>.chkIsSetterPrivate.IsChecked.Value,
    <span style="color:blue;">Me</span>.txtPropertyName.Text,
    <span style="color:blue;">Me</span>.txtBackingField.Text,
    <span style="color:blue;">Me</span>.cboTypeName.SelectedItem.ToString,
    <span style="color:blue;">Me</span>.cboRaisePropertyChangedMethodName.SelectedItem.ToString)

<span style="color:green;">'How cool is this?  Instantiate, call a single method, get the code!
</span><span style="color:blue;">Dim </span>strResult <span style="color:blue;">As String </span>= t.TransformText</pre>
</div>
<p>Instantiate the template, call the TransformText method.&#160; Not very sexy, but powerful!</p>
<h4>Download</h4>
<p><a href="http://cid-51de981e071f222b.skydrive.live.com/self.aspx/Public/T4%20Preprocessed%20Text%20Templates/GetYourT4On.zip" target="_blank">Get Your T4 On Demo Application (33KB)</a></p>
<p><strong>Alternate Download Site </strong></p>
<p>Some corporate firewalls do not allow access to Windows Live Sky Drive. You can download the installer here. Remember to rename the file from .doc to .zip. This is a requirement of WordPress.</p>
<p><a href="http://karlshifflett.files.wordpress.com/2009/10/getyourt4on-zip.doc" target="_blank">Get Your T4 On Demo Application (33KB)</a></p>
<h4>Links</h4>
<p><a href="http://blogs.msdn.com/garethj/" target="_blank">Gareth Jones blog</a>&#160; Gareth works on the DSL Team at Microsoft and works with the Microsoft T4 product.</p>
<p><a href="http://msmvps.com/blogs/kathleen/" target="_blank">Kathleen Dollard’s blog</a> Kathleen has been doing code generation for a very long time and is an industry expert in this space.</p>
<p><a href="http://blogs.appventure.com/Kathleen/2009/09/04/WhyIsAPreprocessedTemplateTheCoolestThingSinceSlicedBread.aspx" target="_blank">Kathleen Dollard’s</a> work blog post on why T4 Templates are the best thing since sliced bread.</p>
<p><a href="http://www.olegsych.com/2009/09/t4-preprocessed-text-templates/" target="_blank">Oleg Sych</a> very nice blog post on T4 Preprocessed Text Templates</p>
<p><a href="http://www.clariusconsulting.net/blogs/pga/archive/2009/07/15/160836.aspx" target="_blank">Pablo Galiano</a> T4 Preprocessing Part 1</p>
<p><a href="http://www.clariusconsulting.net/blogs/pga/archive/2009/07/15/160853.aspx" target="_blank">Pablo Galiano</a> T4 Preprocessing Part 2</p>
<h4>Close</h4>
<p>There is a fair amount of information on Visual Studio 2005/2008 T4 templates.&#160; When reading these blog posts, magazine articles and MSDN Documentation, keep in mind that the new T4 templates do not have wide spread documentation yet.&#160; Most of what you will find is applicable to editing of the templates and directives used in the templates.&#160; Beyond that, just filter the information and you’ll stay on course.</p>
<p>Visual Studio 2010 T4 Preprocessed Text Templates are a great tool for your toolbox.&#160; Hope to see you use the best kept secret in Redmond.</p>
<p>Have a great day,</p>
<p><font color="#c0943f">Just a grain of sand on the worlds beaches.</font></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Introducing oraddlscript]]></title>
<link>http://devio.wordpress.com/2009/10/25/introducing-oraddlscript/</link>
<pubDate>Sun, 25 Oct 2009 10:31:15 +0000</pubDate>
<dc:creator>devio</dc:creator>
<guid>http://devio.wordpress.com/2009/10/25/introducing-oraddlscript/</guid>
<description><![CDATA[A recent question on StackOverflow inspired me to write a utility called oraddlscript: How to genera]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>A recent <a href="http://stackoverflow.com/questions/1564347/oracle-how-to-generate-script-from-sql-developer" target="_blank">question on StackOverflow</a> inspired me to write a utility called <a href="http://www.devio.at/index.php/oraddlscript" target="_blank">oraddlscript</a>:<br />
<img src="http://static.devio.at/t.gif?http://devio.wordpress.com/2009/10/25/introducing-oraddlscript" alt="" width="1" height="1" /></p>
<blockquote><p>How to generate scripts for Oracle schema objects, such as tables, procedures, etc.</p></blockquote>
<p>The answers directed me to the DBMS_METADATA package (<a href="http://download.oracle.com/docs/cd/B10500_01/appdev.920/a96612/d_metada.htm">9i documentation</a>, <a href="http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_metada.htm" target="_blank">10g documentation</a>). The function DBMS_METADATA.GET_DDL is the functional equivalent of the MSSQL SMO library, which prompted me to adapt my command-line utility <a href="http://devio.wordpress.com/category/smoscript/" target="_blank">SMOscript</a> to Oracle databases. Voilà, <a href="http://www.devio.at/index.php/oraddlscript" target="_blank">oraddlscript</a>.</p>
<pre>oraddlscript 0.14.3584.16268 (c) by devio.at 2009

    list and script databases and database objects.

    usage: oraddlscript [options] [command]

    options: (leading '-' or '/')

    -s server       TNS name or host name or host:port
    -svc service    service name (if host name is provided)
    -o owner        owner name

    -u username     username (default: integrated authentication)
    -p password     password (if -u is missing, password for sa)

    -f filename     output to file
    -F directory    output to directory

    -A              current ANSI codepage
    -O              ASCII
    -T              Unicode
    -U              UTF8

    commands:

    l               list objects
    s               script object/s (using dbms_meta.get*ddl)
    -xml            use dbms_meta.get*xml

    list object owners on server (implied by -s)
    list objects in database (implied by -s -o)
    script all objects (implied by -s -o -F/-f)
</pre>
<p>The command-line arguments are consistent with SMOscript, except for -d (database) which has been replaced by -o (owner name).</p>
<p>The list of objects is retrieved by querying DBA_OBJECTS, ALL_OBJECTS and USER_OBJECTS depending on which of the catalog views is accessible by the user specified by -u.</p>
<p>The package also contains a function GET_XML which is used to retrieve the XML representation of a database object.</p>
<p>The functions of oraddlscript are:</p>
<ul>
<li>list usernames of object owners</li>
<li>list objects of specific owner</li>
<li>generate CREATE scripts of objects owned by specific user</li>
<li>generate XML files representing objects owned by specific user</li>
<li>generate one file per object or single file for all objects</li>
</ul>
<p>Of course, <a href="http://devio.wordpress.com/2009/10/17/scripting-all-ms-sql-databases-using-smoscript/" target="_blank">logging and batch operations</a> work just as previously described for SMOscript.</p>
<p>oraddlscript is <a href="http://gforge.devio.at/projects/oraddlscript/" target="_blank">available for download here</a>.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[dbscript New Version 0.99]]></title>
<link>http://devio.wordpress.com/2009/10/20/dbscript-new-version-0-99/</link>
<pubDate>Tue, 20 Oct 2009 19:03:52 +0000</pubDate>
<dc:creator>devio</dc:creator>
<guid>http://devio.wordpress.com/2009/10/20/dbscript-new-version-0-99/</guid>
<description><![CDATA[The latest version 0.99 of dbscript has been released today providing new functionality and a couple]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>The latest version 0.99 of <a href="http://www.devio.at/index.php/dbscript" target="_blank">dbscript</a> has been released today providing new functionality and a couple of fixes.<img src="http://static.devio.at/t.gif?http://devio.wordpress.com/2009/10/20/dbscript-new-version-0-99" alt="" width="1" height="1" /></p>
<p>Data diagrams looked a bit distorted if the data model contained circular foreign key constraints. I sketched the problem in my <a href="http://devio.wordpress.com/2009/09/13/finding-cycles-in-directed-graphs-using-tsql/" target="_blank">article on cycle detection</a>, and the data diagram now excludes circular foreign keys in the calculation of the tables&#8217; positions.</p>
<p>Comparison results can be restricted to &#8220;scopes&#8221;, such as new objects only, dropped objects only, etc. This makes it easier to generate schema migration scripts without dropping objects, for example.</p>
<p>Documentation Generators provide a preview to the generated content, and the generated XML now contains the project and project version identifiers to enable linking and referencing in the generator&#8217;s output.</p>
<p>Scripting a table in the object&#8217;s Generate/Create page now includes all constraints and indexes. (The project version script always included child objects). The same applies to object comparisons of tables, so that changes to indexes etc are easily identifiable.</p>
<p><strong>New Functions</strong></p>
<p>Besides generating .png data diagrams, dbscript now has the capability to generate data diagrams for <a href="http://live.gnome.org/Dia" target="_blank">Dia</a>, an open-source diagrammer. The layout routine is the same as for png&#8217;s, but the output is Dia&#8217;s native XML format. Generating for Dia means that developers can freely layout and edit the diagram according to their needs, and export it to other formats. I described this feature <a href="http://devio.wordpress.com/2009/09/27/creating-dia-data-diagrams-from-database-schema/" target="_blank">earlier, and included samples</a>.</p>
<p>Schema comparison is one basic feature of dbscript, and the new version compares multiple versions in one operation. After defining which schema versions to compare, you get a <a href="http://devio.wordpress.com/2009/10/05/multi-version-comparison/" target="_blank">comparison matrix showing the number of differences between any two versions</a>.</p>
<p>If the selected versions are versions of the same schema at different points of time, the <a href="http://devio.wordpress.com/2009/10/08/multi-version-comparison-timeline/" target="_blank">comparison timeline shows each object ever changing in any of the versions</a>, along with an indicator of the change.</p>
<p>Within a project, you can define Branches (as known from version control systems) and assign project versions to a branch. This alone would not be too overwhelming, but branches are a precondition of the update notification system, which I will describe in a future post.</p>
<p>The latest version of <a href="https://gforge.devio.at/frs/?group_id=10" target="_blank">dbscript is available for download here</a>.</p>
<p>Please leave comments and feedback.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Code Generation with PowerShell and TFS]]></title>
<link>http://devio.wordpress.com/2009/10/15/code-generation-with-powershell-and-tfs/</link>
<pubDate>Thu, 15 Oct 2009 07:45:52 +0000</pubDate>
<dc:creator>devio</dc:creator>
<guid>http://devio.wordpress.com/2009/10/15/code-generation-with-powershell-and-tfs/</guid>
<description><![CDATA[If you use PowerShell to automatically generate code for your project (e.g. during the build process]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>If you use <a href="http://devio.wordpress.com/category/powershell/" target="_blank">PowerShell</a> to automatically <a href="http://devio.wordpress.com/category/code-generation/" target="_blank">generate code</a> for your project (e.g. during the build process) and you work in  TFS-based code, you need to check out existing files before overwriting them. Otherwise the files are read-only and/or not stored in TFS after code generation.<img src="http://static.devio.at/t.gif?http://devio.wordpress.com/2009/10/25/code-generation-with-powershell-and-tfs" alt="" width="1" height="1" /></p>
<p>The PowerShell stub script to handle this situation looks like this (assuming the .ps1 file is also inside a TFS directory):</p>
<pre>$scriptdir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
$basepath = $scriptdir.Substring(0, $scriptdir.Length - "path\from\tfs-base\to\script".Length)
</pre>
<p>$scriptdir stores the directory name of the currently executed script. If the script file is stored inside your TFS project, you can calculate the file path to checkout from $scriptdir.</p>
<p>Next, we call TFS checkout, generate code, and check in again:</p>
<pre>&#38; .\tf-checkout.cmd $basepath
... Code generation is here ...
&#38; .\tf-checkin.cmd $basepath</pre>
<p>tf-checkout.cmd needs to set the Visual Studio environment variables (as in Visual Studio Command Prompt) to execute the &#8220;tf checkout&#8221; command:</p>
<pre>@echo off
setlocal
call "c:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" x86

echo.
echo checking out...

tf checkout %1path\to\file1.cs
tf checkout %1path\to\file2.cs
...

endlocal</pre>
<p>tf-checkin.cmd looks similar:</p>
<pre>@echo off
setlocal
call "c:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" x86

echo.
echo checking in...

tf checkin /comment:autogenerated /noprompt %1path\to\file1.cs
tf checkin /comment:autogenerated /noprompt %1path\to\file2.cs

endlocal</pre>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Alloy in real projects]]></title>
<link>http://ckoeppe.wordpress.com/2009/10/13/alloy-in-real-projects/</link>
<pubDate>Tue, 13 Oct 2009 09:37:29 +0000</pubDate>
<dc:creator>Christian Köppe</dc:creator>
<guid>http://ckoeppe.wordpress.com/2009/10/13/alloy-in-real-projects/</guid>
<description><![CDATA[In my master we use Alloy (http://alloy.mit.edu/) for formal specifications of software using first-]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>In my master we use Alloy (<a>http://alloy.mit.edu/</a>) for formal specifications of software using first-order logic. Alloy is quite a nice and powerful tool, but what in my opinion is missing is that you can reuse the models developed in Alloy in real software projects. Therefore Alloy is at this moment more a tool to develop your logic (and sets) skills and it sure helps you to understand the necessarity of formal specifying software if you wanna validate the quality of it. But: it doesn&#8217;t help you in real projects (besides if you call finding solutions to sudoku of river crossing puzzles real projects, well then&#8230;).</p>
<p>There are attempts to create this link, namely DynAlloy, VAlloy and there is also a master thesis from a UvA-student implementing a Javacode-generator based on Alloy models. But all these still have drawbacks which won&#8217;t be discussed here. </p>
<p>So one of the questions I&#8217;ll be working on in the next time is: how can one create this link making Alloy a powerful tool for developing reliable, validated en testable REAL software projects.</p>
<p>If there are already further attempts to do this, please let me know. No one wants to do work which has already be done&#8230; and I&#8217;m always willing to cooperate with other people.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Handling Grants in a Function Hierarchy]]></title>
<link>http://devio.wordpress.com/2009/09/29/handling-grants-in-a-function-hierarchy/</link>
<pubDate>Tue, 29 Sep 2009 06:58:48 +0000</pubDate>
<dc:creator>devio</dc:creator>
<guid>http://devio.wordpress.com/2009/09/29/handling-grants-in-a-function-hierarchy/</guid>
<description><![CDATA[Applications usually implement some kind of security or grant management which allows a user to perf]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Applications usually implement some kind of security or grant management which allows a user to perform certain operations or restricts them from invoking them. This post presents a generic way of handling grants in a function hierarchy.<img src="http://static.devio.at/t.gif?http://devio.wordpress.com/2009/09/29/handling-grants-in-a-function-hierarchy" alt="" width="1" height="1" /></p>
<p>First we need a list of all functions in the application. For illustration, I use a simple shop application with a minimal set of functions. A function can be a general operation, or an operation on a certain database record:</p>
<pre>CREATE TABLE #Functions (
	ID	INT NOT NULL PRIMARY KEY,
	Name	NVARCHAR(50),
	ParentFunctionID INT NULL, -- REFERENCES #Functions (ID),
	Parameter1 	NVARCHAR(50),
	-- optionally more parameters
	CargoParameters	NVARCHAR(50),
	ResultType	NVARCHAR(50)
)

SET NOCOUNT ON 

INSERT INTO #Functions (ID, Name, CargoParameters, ResultType)
  VALUES (1, 'CreateProduct', 'ProductDescription pd', 'int')
INSERT INTO #Functions (ID, Name, ParentFunctionID, Parameter1)
  VALUES (10, 'ManageProduct', NULL, 'ProductID')
INSERT INTO #Functions (ID, Name, ParentFunctionID, Parameter1)
  VALUES (11, 'EditProduct', 10, 'ProductID')
INSERT INTO #Functions (ID, Name, ParentFunctionID, Parameter1)
  VALUES (12, 'RemoveProduct', 10, 'ProductID')
INSERT INTO #Functions (ID, Name) VALUES (20, 'GoShopping')
INSERT INTO #Functions (ID, Name, ParentFunctionID)
  VALUES (21, 'ListProducts', 20)
INSERT INTO #Functions (ID, Name, ParentFunctionID, Parameter1, CargoParameters, ResultType)
  VALUES (22, 'AddToCart', 20, 'ProductID', 'int Quantity', 'ShoppingResult')

SELECT * FROM #Functions</pre>
<p>This results in the following table:</p>
<table border="0">
<tbody>
<tr>
<td>ID</td>
<td>Name</td>
<td>Parent FunctionID</td>
<td>Parameter1</td>
<td>CargoParameters</td>
<td>ResultType</td>
</tr>
<tr>
<td>1</td>
<td>CreateProduct</td>
<td>NULL</td>
<td>NULL</td>
<td>ProductDescription pd</td>
<td>int</td>
</tr>
<tr>
<td>10</td>
<td>ManageProduct</td>
<td>NULL</td>
<td>ProductID</td>
<td>NULL</td>
<td>NULL</td>
</tr>
<tr>
<td>11</td>
<td>EditProduct</td>
<td>10</td>
<td>ProductID</td>
<td>NULL</td>
<td>NULL</td>
</tr>
<tr>
<td>12</td>
<td>RemoveProduct</td>
<td>10</td>
<td>ProductID</td>
<td>NULL</td>
<td>NULL</td>
</tr>
<tr>
<td>20</td>
<td>GoShopping</td>
<td>NULL</td>
<td>NULL</td>
<td>NULL</td>
<td>NULL</td>
</tr>
<tr>
<td>21</td>
<td>ListProducts</td>
<td>20</td>
<td>NULL</td>
<td>NULL</td>
<td>NULL</td>
</tr>
<tr>
<td>22</td>
<td>AddToCart</td>
<td>20</td>
<td>ProductID</td>
<td>int Quantity</td>
<td>ShoppingResult</td>
</tr>
</tbody>
</table>
<p>Once we have the complete list of all functions, we can generate code to implement a number of methods for each function:</p>
<table border="0">
<tbody>
<tr>
<td>IsPossibleToX</td>
<td>Is it possible to execute function X now (depending on the information / status of the record</td>
</tr>
<tr>
<td>IsUserAllowedToX</td>
<td>Does the user have sufficient rights to execute X</td>
</tr>
<tr>
<td>ExecuteX</td>
<td>Invoke execution of function with parameters and result value</td>
</tr>
</tbody>
</table>
<p><!--more-->In this post, I use a class named UserContext which identifies the current user and encapsulates the way the user is identified: whether it is a Guid, an integer, is not relevant for this code.</p>
<p>The usual TSQL cursor magic:</p>
<pre>DECLARE @Name NVARCHAR(50), @Parameter1 NVARCHAR(50), @FP_Name NVARCHAR(50),
  @FP_Parameter1 NVARCHAR(50)
DECLARE @CargoParameters NVARCHAR(50), @ResultType NVARCHAR(50)

PRINT 'public partial class FunctionBase
{'

DECLARE c CURSOR FOR
SELECT F.Name, F.Parameter1, FP.Name AS FP_Name, FP.Parameter1 AS FP_Parameter1,
  F.CargoParameters, F.ResultType
FROM #Functions F
LEFT OUTER JOIN #Functions FP ON F.ParentFunctionID = FP.ID
ORDER BY F.ID

OPEN c
FETCH c INTO @Name, @Parameter1, @FP_Name, @FP_Parameter1, @CargoParameters,
  @ResultType

WHILE @@FETCH_STATUS = 0 BEGIN
</pre>
<p>For each of the methods above, we generate a C# method with the default behavior:</p>
<ul>
<li>If the function has a parent, call the parent.</li>
<li>If the function has no parent, return false.</li>
<li>The Execute method throws an exception.</li>
</ul>
<pre>  PRINT '	public virtual bool IsPossibleTo' + @Name + '(' +
    CASE WHEN @Parameter1 IS NOT NULL THEN 'int ' + @Parameter1 ELSE '' END + ')'
  PRINT '	{'

  IF @FP_Name IS NULL
    PRINT '		return false;'
  ELSE IF ISNULL(@Parameter1, '') = ISNULL(@FP_Parameter1, '')
    PRINT '		return IsPossibleTo' + @FP_Name + '(' + ISNULL(@Parameter1, '') + ');'
  ELSE IF @FP_Parameter1 IS NULL
    PRINT '		return IsPossibleTo' + @FP_Name + '();'
  ELSE -- no @param, but @fpparam
    PRINT '		return IsPossibleTo' + @FP_Name + '(0);'

  PRINT '	}'

  PRINT '	public virtual bool IsUserAllowedTo' + @Name + '(UserContext u' +
    CASE WHEN @Parameter1 IS NOT NULL THEN ', int ' + @Parameter1 ELSE '' END + ')'
  PRINT '	{'

  IF @FP_Name IS NULL
    PRINT '		return false;'
  ELSE IF ISNULL(@Parameter1, '') = ISNULL(@FP_Parameter1, '')
    PRINT '		return IsUserAllowedTo' + @FP_Name + '(u' +
      CASE WHEN @Parameter1 IS NOT NULL THEN ', ' + @Parameter1 ELSE '' END + ');'
  ELSE IF @FP_Parameter1 IS NULL
    PRINT '		return IsUserAllowedTo' + @FP_Name + '(u);'
  ELSE -- no @param, but @fpparam
    PRINT '		return IsUserAllowedTo' + @FP_Name + '(u, 0);'

  PRINT '	}'

  PRINT '	public virtual ' + ISNULL(@ResultType, 'void') + ' Do' + @Name + '(UserContext u' +
    CASE WHEN @Parameter1 IS NOT NULL THEN ', int ' + @Parameter1 ELSE '' END +
    CASE WHEN @CargoParameters IS NOT NULL THEN ', ' + @CargoParameters ELSE '' END +
    ')'
  PRINT
'	{
		throw new Exception("FunctionBase.Do' + @Name + ' is not implemented");
	}'
</pre>
<p>End of cursor code:</p>
<pre>  FETCH c INTO @Name, @Parameter1, @FP_Name, @FP_Parameter1,
    @CargoParameters, @ResultType

END

CLOSE c
DEALLOCATE c

PRINT '}'

DROP TABLE #Functions
</pre>
<p>This results in a class FunctionBase which implements security methods for each function, such as:</p>
<pre>public partial class FunctionBase
{
  public virtual bool IsPossibleToCreateProduct()
  {
    return false;
  }
  public virtual bool IsUserAllowedToCreateProduct(UserContext u)
  {
    return false;
  }
  public virtual int DoCreateProduct(UserContext u, ProductDescription pd)
  {
    throw new Exception("FunctionBase.DoCreateProduct is not implemented");
  }</pre>
<p>Not too impressive at first glance, but look at EditProduct, which is below ManageProduct in the function hierarchy:</p>
<pre>  public virtual bool IsPossibleToManageProduct(int ProductID)
  {
    return false;
  }
  public virtual bool IsUserAllowedToManageProduct(UserContext u, int ProductID)
  {
    return false;
  }
  public virtual void DoManageProduct(UserContext u, int ProductID)
  {
    throw new Exception("FunctionBase.DoManageProduct is not implemented");
  }
  public virtual bool IsPossibleToEditProduct(int ProductID)
  {
    return IsPossibleToManageProduct(ProductID);
  }
  public virtual bool IsUserAllowedToEditProduct(UserContext u, int ProductID)
  {
    return IsUserAllowedToManageProduct(u, ProductID);
  }
  public virtual void DoEditProduct(UserContext u, int ProductID)
  {
    throw new Exception("FunctionBase.DoEditProduct is not implemented");
  }
</pre>
<p>The IsPossibleToEditProduct and IsUserAllowedToEditProduct methods automatically inherit the result from IsPossibleToManageProduct and IsUserAllowedToManageProduct.</p>
<p>What would be the value of a generated function which only throws exceptions, you might ask. Well, this is the point where the actual coding begins:</p>
<pre>public partial class Function : FunctionBase
{
  private static Function _instance;
  public static Function Instance
  {
    get
    {
      if (_instance == null)
        _instance = new Function();
      return _instance;
    }
  }

  public override bool IsPossibleToManageProduct(int ProductID)
  {
    // implement your checks here, all functions below ManageProduct inherit this result by default
    return Result;
  }
  public override bool IsUserAllowedToManageProduct(UserContext u, int ProductID)
  {
    // implement your checks here, all functions below ManageProduct inherit this result by default
    return Result;
  }
  public virtual void DoEditProduct(UserContext u, int ProductID)
  {
    // implement your function here
  }
}
</pre>
<p>And to check, whether an operation is possible and allowed, use:</p>
<pre>UserContext uc = RetrieveUserContext();
int id = RetrieveRecordIdentifier();
if (Function.Instance.IsPossibleToEditProduct(id) &#38;&#38;
    Function.Instance.IsUserAllowedToEditProduct(uc, id))
  Function.Instance.DoEditProduct(uc, id);
</pre>
<p>Note that you can define additional parameters and a result type for the execution method.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Version 0.98 of dbscript Released]]></title>
<link>http://devio.wordpress.com/2009/09/09/version-0-98-of-dbscript-released/</link>
<pubDate>Wed, 09 Sep 2009 20:14:34 +0000</pubDate>
<dc:creator>devio</dc:creator>
<guid>http://devio.wordpress.com/2009/09/09/version-0-98-of-dbscript-released/</guid>
<description><![CDATA[The latest version 0.98 of dbscript supports PostgreSQL databases in its documentation generation ca]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>The latest version 0.98 of <a href="http://www.devio.at/index.php/dbscript" target="_blank">dbscript</a> supports <a href="http://www.postgresql.org/" target="_blank">PostgreSQL databases</a> in its <a href="http://devio.wordpress.com/category/documentation-generation/" target="_blank">documentation generation</a> capabilities.<img src="http://static.devio.at/t.gif?http://devio.wordpress.com/2009/09/09/version-0-98-of-dbscript-released" alt="" width="1" height="1" /></p>
<p>After importing the database dictionary (via direct connection using ADO.Net and <a href="http://npgsql.projects.postgresql.org/" target="_blank">Npgsql</a>) can document a PostgreSQL database in all currently supported documentation format:</p>
<p><a href="http://devio.wordpress.com/2009/08/07/creating-mediawiki-documentation-of-postgresql-databases/" target="_blank">MediaWiki</a></p>
<p><a href="http://devio.wordpress.com/2009/08/07/creating-mediawiki-documentation-of-postgresql-databases/" target="_blank">Data Diagram</a> (PNG)</p>
<p><a href="http://devio.wordpress.com/2009/08/10/creating-html-documentation-of-postgresql-databases/" target="_blank">HTML</a></p>
<p><a href="http://devio.wordpress.com/2009/08/29/generating-database-documentation-for-screwturn-wikis/" target="_blank">ScrewTurn wiki</a></p>
<p>Integration support for PostgreSQL had some consequences: More and more functionality is handled separately for each database engine.</p>
<p>Database import was obviously the first one, since the data access classes (SqlConnection, SqlCommand) in .Net are different for every database library. Same goes for the database dictionary, which is best retrieve from the native system catalogs.</p>
<p>For import and upload, data access classes have been introduced to distinguish the different object types and their properties of each database engine. I mention work on the <a href="http://devio.wordpress.com/2009/09/09/creating-a-light-weight-data-access-layer-in-c-6/" target="_blank">data access classes</a> in a series of articles already.</p>
<p>In version 0.98, XML generation and object script generation are implemented separately. This results in XSL style sheets being now related to certain a database engine.</p>
<p>For Oracle, XML and object script generation have been updated, and the XSL style sheets have been adjusted to Oracle-specific objects and properties. The <a href="http://devio.wordpress.com/2009/08/26/documenting-oracle-databases-2/" target="_blank">results were documented earlier</a>.</p>
<p>The latest version of <a href="https://gforge.devio.at/frs/?group_id=10" target="_blank">dbscript is available for download here</a>.</p>
<p>Please leave comments and feedback.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Creating a light-weight Data Access Layer in C# (6)]]></title>
<link>http://devio.wordpress.com/2009/09/09/creating-a-light-weight-data-access-layer-in-c-6/</link>
<pubDate>Wed, 09 Sep 2009 07:01:50 +0000</pubDate>
<dc:creator>devio</dc:creator>
<guid>http://devio.wordpress.com/2009/09/09/creating-a-light-weight-data-access-layer-in-c-6/</guid>
<description><![CDATA[Part 1: Retrieve information on tables and columns Part 2: SELECT record, access record fields Part ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Part 1: <a href="http://devio.wordpress.com/2009/07/27/creating-a-light-weight-data-access-layer-in-c-1/" target="_blank">Retrieve information on tables and columns</a><img src="http://static.devio.at/t.gif?http://devio.wordpress.com/2009/09/09/creating-a-light-weight-data-access-layer-in-c-6" alt="" width="1" height="1" /></p>
<p>Part 2: <a href="http://devio.wordpress.com/2009/07/28/creating-a-light-weight-data-access-layer-in-c-2/" target="_blank">SELECT record, access record fields</a></p>
<p>Part 3: <a href="http://devio.wordpress.com/2009/07/29/creating-a-light-weight-data-access-layer-in-c-3/" target="_blank">SELECT records, INSERT</a></p>
<p>Part 4: <a href="http://devio.wordpress.com/2009/07/30/creating-a-light-weight-data-access-layer-in-c-4/" target="_blank">Generating C# classes</a></p>
<p>Part 5: <a href="http://devio.wordpress.com/2009/08/04/creating-a-light-weight-data-access-layer-in-c-5/" target="_blank">Generated C# classes and polymorphism</a></p>
<p>Part 6: UPDATE record</p>
<p>Our DAL object has two collections, with dictNew holding new values, and dictRecord for previously inserted or retrieved values. To implement an Update() method, the Insert() method has to be fixed to save the inserted values:</p>
<pre>   dictRecord = dictNew;
   dictNew = null;</pre>
<p>Now we are ready to implement UPDATE. The parameters are collected similarly as described in part 3, which describes the INSERT operation:</p>
<pre>private void Update(SqlConnection conn)
{
    if (IdentityColumn != null)
    {
        if (!dictRecord.ContainsKey(IdentityColumn))
            throw new Exception("UPDATE " + this.TableName + " without IDENTITY column set");

        StringBuilder sb = new StringBuilder();
        sb.Append("UPDATE " + TableName + " SET ");

        bool bFirst = true;
        foreach (string s in dictNew.Keys)
        {
            if (!bFirst)
                sb.Append(", ");
            sb.Append(s + " = @" + s);
            bFirst = false;
        }

        sb.Append(" WHERE " + IdentityColumn + " = @" + IdentityColumn);

        SqlCommand cmd = new SqlCommand();
        cmd.Connection = conn;

        foreach (string s in dictNew.Keys)
        {
            if (dictNew[s] == null)
                cmd.Parameters.AddWithValue("@" + s, DBNull.Value);
            else
                cmd.Parameters.AddWithValue("@" + s, dictNew[s]);
        }

        cmd.Parameters.AddWithValue("@" + IdentityColumn, dictRecord[IdentityColumn]);
        cmd.CommandText = sb.ToString();

        foreach (string s in dictNew.Keys)
            if (dictRecord.ContainsKey(s))
                dictRecord[s] = dictNew[s];
            else
                dictRecord.Add(s, dictNew[s]);

        dictNew = null;
    }
    else
        throw new Exception("UPDATE " + this.TableName + " without IDENTITY column is not implemented.");
}</pre>
<p>If the table does not have an IDENTITY column, the WHERE condition for the UPDATE is unknown and an exception is raised. If the identity column of the existing record is not set, an exception is raised, too.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Code Generation Resources]]></title>
<link>http://dukedomain.wordpress.com/2009/09/08/code-generation-resources/</link>
<pubDate>Tue, 08 Sep 2009 01:17:35 +0000</pubDate>
<dc:creator>dukedomain</dc:creator>
<guid>http://dukedomain.wordpress.com/2009/09/08/code-generation-resources/</guid>
<description><![CDATA[http://weblogs.java.net/blog/edburns/archive/2009/09/03/dealing-gracefully-viewexpiredexception-jsf2]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a class="wp-caption-dd" href="http://weblogs.java.net/blog/edburns/archive/2009/09/03/dealing-gracefully-viewexpiredexception-jsf2" target="_blank">http://weblogs.java.net/blog/edburns/archive/2009/09/03/dealing-gracefully-viewexpiredexception-jsf2</a></p>
<p><a class="wp-caption-dd" href="http://weblogs.java.net/blog/rogerk/archive/2009/09/04/contexts-and-dependency-injection-jsr-299-and-glassfish" target="_blank">http://weblogs.java.net/blog/rogerk/archive/2009/09/04/contexts-and-dependency-injection-jsr-299-and-glassfish</a></p>
<p><a class="wp-caption-dd" href="http://martinfowler.com/bliki/FluentInterface.html" target="_blank">http://martinfowler.com/bliki/FluentInterface.html</a></p>
<p><a class="wp-caption-dd" href="http://martinfowler.com/dslwip/" target="_blank">http://martinfowler.com/dslwip/</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[هل سمعت بـ T4 ؟]]></title>
<link>http://alnabhani.wordpress.com/2009/09/08/%d9%87%d9%84-%d8%b3%d9%85%d8%b9%d8%aa-%d8%a8%d9%80-t4-%d8%9f/</link>
<pubDate>Mon, 07 Sep 2009 20:32:33 +0000</pubDate>
<dc:creator>alnabhani</dc:creator>
<guid>http://alnabhani.wordpress.com/2009/09/08/%d9%87%d9%84-%d8%b3%d9%85%d8%b9%d8%aa-%d8%a8%d9%80-t4-%d8%9f/</guid>
<description><![CDATA[ان كنت قد تجولت في مواقع الانترنت ذات العلاقه بمايكروسوفت ، فأكيد ان صداعا في الرأس بدأ يصيبك من رؤي]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p align="justify">ان كنت قد تجولت في مواقع الانترنت ذات العلاقه بمايكروسوفت ، فأكيد ان صداعا في الرأس بدأ يصيبك من رؤية بعض المصطلحات المعتمدة في الاصدرات القادمة ابرزها T4 ، فعشرات المواقع والمجلات والمدونات تتحدث عن T4 واجزم انك رأيت ذلك المصطلح امامك عشرات المرات ! والسؤال الذي يطرح نفسه : ماذا يقصد بـ T4 ؟ </p>
<p align="justify">T4 هو رمز الى عبارة Text Templating Transformation Toolkit &#8211; اي حرف T اربع مرات بدل TTTT !! &#8211; وهي تقنية طورتها مايكروسوفت سابقا وقد قامت حاليا برفع متسوى تطويرها الى مرحلة متقدمة جدا ، هذه التقنية تستخدم في توليد الاكواد Code Generation في مختلف منتجات مايكروسوفت وابرزها بطبيعه الحال Visual Studio .&#160; </p>
<p align="justify">محرك T4 موجود اصلا في النسخه 2008 وقادم بشكل قوي جدا في 2010 ، ففي الاصدار الحالي لايوجد اي اداة Tool لاستخدامها في اعادة توليد الاكواد الروتينية ، ولكن في الاصدار 2010 فالوضع مختلف حقا من هذه الناحية ، وبالنسبه للاصدار 2008 فيمكنك استخدام ادوات خارجيه تؤدي هذا الغرض منها اداة Visual T4 Editor و Visual T4 Code Generator وبعضها يتوفر في اصدارات مجانية وهي تتميز بإندماجها بشكل كلي مع Visual Studio . </p>
<p align="justify">موقع الاداة Visual T4 هو : <a href="http://www.visualt4.com/">http://www.visualt4.com/</a>    <br />وموقع الاداة&#160; Visual T4 Code Generator هو :</p>
<p align="justify"><a title="http://t4-editor.tangible-engineering.com/T4-Editor-Visual-T4-Editing.html" href="http://t4-editor.tangible-engineering.com/T4-Editor-Visual-T4-Editing.html">http://t4-editor.tangible-engineering.com/T4-Editor-Visual-T4-Editing.html</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Role of Code Generation in Java Application Developmentについて]]></title>
<link>http://view5.wordpress.com/2009/09/04/role-of-code-generation-in-java-application-development%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6/</link>
<pubDate>Fri, 04 Sep 2009 10:49:05 +0000</pubDate>
<dc:creator>rmodp</dc:creator>
<guid>http://view5.wordpress.com/2009/09/04/role-of-code-generation-in-java-application-development%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6/</guid>
<description><![CDATA[MDDつながりです。InfoQに次の記事がありました。 Role of Code Generation in Java Application Development Javaの世界を中心にCode ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>MDDつながりです。InfoQに次の記事がありました。</p>
<ol>
<li><a href="http://www.infoq.com/news/2009/09/codegen-java-development">Role of Code Generation in Java Application Development</a></li>
</ol>
<p>Javaの世界を中心にCode Generationを実践する各種ツールを紹介し将来の展望を実践者にインタビューしています。</p>
<p>本ブログではこの方向性が正しくまた避けられないものだと考えています。各種ツールはすべて進化の途上にあり、どれを選ぶかはあるタイミングにおいてもケースバイケースですし、またどれかが急に進化する可能性もあるため、常に広く状況を観察する必要があります。</p>
<p>まだ試された事の無い方は、一度上の記事にあるツール（主なものはカバーされているようです）のデモビデオなどをご覧ください。何か得るものが有るかもしれません。</p>
<p>補足）偶然かもしれませんがSpringSourceのRooの開発者によるRooの説明ビデオがInfoQに掲載されていました。最後の箇所はRoRを意識しているということでしょうか。</p>
<ol>
<li><a href="http://www.infoq.com/presentations/Roo-Ben-Alex">Extreme Productivity in Application Development with Roo</a></li>
</ol>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Using Preprocessed Text Templates]]></title>
<link>http://lessisthenewmore.wordpress.com/2009/08/20/using-preprocessed-text-templates/</link>
<pubDate>Thu, 20 Aug 2009 22:37:35 +0000</pubDate>
<dc:creator>fromano</dc:creator>
<guid>http://lessisthenewmore.wordpress.com/2009/08/20/using-preprocessed-text-templates/</guid>
<description><![CDATA[In order to explore Preprocessed Text Templates a bit further, this post shows a small example using]]></description>
<content:encoded><![CDATA[In order to explore Preprocessed Text Templates a bit further, this post shows a small example using]]></content:encoded>
</item>
<item>
<title><![CDATA[Recording API Invocations for Debugging]]></title>
<link>http://cdivilly.wordpress.com/2009/08/20/recording-api-invocations-for-debugging/</link>
<pubDate>Thu, 20 Aug 2009 13:06:13 +0000</pubDate>
<dc:creator>cdivilly</dc:creator>
<guid>http://cdivilly.wordpress.com/2009/08/20/recording-api-invocations-for-debugging/</guid>
<description><![CDATA[Today I encountered a problem when using the Oracle JDBC API that only manifested itself in a certai]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Today I encountered a problem when using the Oracle JDBC API that only manifested itself in a certain complicated sequence of API invocations. I wanted to understand exactly what the sequence of API invocations was and also be able to extract them, so I could spit them out into a standalone test-case that I could use to debug the problem. Below is a class I whipped up to help automate most of this task.</p>
<p>So now I can do something like:</p>
<pre>
Invocations t = new Invocations();
PoolDataSource ods= t.trace(PoolDataSourceFactory.getPoolDataSource(),PoolDataSource.class);

ods.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
ods.setURL("jdbc:oracle:thin://localhost:1521/orcl");
ods.setUser("scott");
ods.setPassword("tiger");
Connection conn = ods.getConnection();
CallableStatement stmt = conn.prepareCall("begin dbms_output.put_line('Hello'); end;");
stmt.execute();
stmt.close();
conn.close();
System.out.print(t);
</pre>
</p>
<p>Which produces the following output:</p>
<pre>
oracle.ucp.jdbc.PoolDataSource v1;
v1.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
v1.setURL("jdbc:oracle:thin://localhost:1521/orcl");
v1.setUser("scott");
v1.setPassword("tiger");
java.sql.Connection v2;
v2 = v1.getConnection();
java.sql.CallableStatement v3;
v3 = v2.prepareCall("begin dbms_output.put_line('Hello'); end;");
boolean v4;
v4 = v3.execute();
v3.close();
v2.close();
</pre>
<p>Which is a pretty good facsimile of the original code. Note there are obviously limitations to what this kind of approach can achieve:</p>
<ul>
<li><code>Invocations</code> can only handle primitive values and values created within the API itself</li>
<li>Any non primitive values (including arrays) created outside of the API can only be declared, code to initialize these values will need to be added manually.</li>
</ul>
<p>The major benefit of the generated code is that it does not have any dependencies other than the API being traced, thus making it easier to extract a stand-alone test case that exhibits the problem. This makes it easier to focus on the problem by eradicating superfluous code. It also very useful when you need a stand-alone test-case for a bug report for a third party API.</p>
<h3>The Source Code</h3>
<p><pre>
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.IdentityHashMap;

public class Invocations {

	@Override
	public String toString() {
		return b.toString();
	}
	public &#60;T&#62; T trace(final Object target, final Class&#60;T&#62; type) {
		return trace(target, type, false);
	}

	private void declare(final Object object, final Class&#60;?&#62; type,
			final boolean force) {
		if (!void.class.equals(type)) {
			if (force
					&#124;&#124; (object != null &#38;&#38; !variables.containsKey(object) &#38;&#38; !isPrimitive(type))) {
				b.append(typeName(type));
				b.append(" ");
				b.append(register(object));
				b.append(";\n");
			}
		}
	}
	private boolean isPrimitive(final Class&#60;?&#62; type) {
		boolean isPrimitive = type.isPrimitive();
		if (!isPrimitive) {
			for (final Class&#60;?&#62; c : PRIMITIVES) {
				if (c.equals(type)) {
					isPrimitive = true;
					break;
				}
			}
		}
		return isPrimitive;
	}
	private String name(final Object object) {
		String name = "null";
		if (object != null) {
			name = variables.get(object);
			if (name == null) {
				if (isPrimitive(object.getClass())) {
					return render(object);
				} else {
					throw new RuntimeException("Could not find name for: "
							+ object);
				}
			}
		}
		return name;
	}
	private String register(final Object object) {
		String name;
		name = variables.get(object);
		if (name == null) {
			name = "v" + (++var);
			variables.put(object, name);
		}
		return name;
	}
	private String render(final Object object) {
		final Class&#60;?&#62; type = object.getClass();
		if (String.class.equals(type)) {
			return "\"" + object.toString() + "\"";
		} else if (short.class.equals(type) &#124;&#124; Short.class.equals(type)) {
			return "(short)" + object.toString();
		} else if (long.class.equals(type) &#124;&#124; Long.class.equals(type)) {
			return object.toString() + "L";
		} else if (char.class.equals(type) &#124;&#124; Character.class.equals(type)) {
			return "'" + object.toString() + "'";
		} else {
			return object.toString();
		}
	}
	@SuppressWarnings("unchecked")
	private &#60;T&#62; T trace(final Object target, final Class&#60;T&#62; type,
			final boolean force) {
		T result = null;
		if (target != null) {
			if (target.getClass().getInterfaces().length &#62; 0
					&#38;&#38; !isPrimitive(target.getClass())) {
				result = type.cast(Proxy.newProxyInstance(Thread
						.currentThread().getContextClassLoader(), target
						.getClass().getInterfaces(), new Recorder(target)));
			} else {
				result = (T) target;
			}
		}
		declare(result, type, force);
		return result;
	}
	private String typeName(final Class&#60;?&#62; type) {
		if (type.isArray()) {
			return typeName(type.getComponentType()) + "[]";
		} else {
			return type.getName();
		}
	}

	private class Recorder implements InvocationHandler {

		Recorder(final Object target) {
			this.target = target;
		}

		public Object invoke(final Object proxy, final Method method,
				final Object[] args) throws Throwable {
			Object result = null;
			final Class&#60;?&#62; type = method.getReturnType();
			try {
				result = method.invoke(target, args);
			} catch (final InvocationTargetException e) {
				final Throwable t = e.getCause();
				for (final Class&#60;?&#62; ex : method.getExceptionTypes()) {
					if (ex.isAssignableFrom(t.getClass())) {
						throw t;
					}
				}
				throw e;
			}
			result = trace(result, type, true);
			record(result, proxy, method, args);
			return result;
		}

		private void record(final Object result, final Object proxy,
				final Method method, final Object[] args) {
			if (args != null) {
				final Class&#60;?&#62;[] types = method.getParameterTypes();
				for (int i = 0; i &#60; args.length; ++i) {
					declare(args[i], types[i], false);
				}
			}
			if (result != null) {
				b.append(name(result));
				b.append(" = ");
			}
			b.append(name(proxy));
			b.append('.');
			b.append(method.getName());
			b.append('(');
			if (args != null) {
				for (int i = 0; i &#60; args.length; ++i) {
					b.append(name(args[i]));
					if (i &#60; args.length - 1) {
						b.append(',');
					}
				}
			}
			b.append(");\n");
		}

		private final Object target;

	};

	private final StringBuilder b = new StringBuilder();

	private int var = 0;

	private final IdentityHashMap&#60;Object, String&#62; variables = new IdentityHashMap&#60;Object, String&#62;();
	private static final Class&#60;?&#62;[] PRIMITIVES = { String.class, Integer.class,
			Boolean.class, Double.class, Long.class, Short.class, Byte.class,
			Character.class, Float.class };
}
</pre>
</p>
<p>I&#8217;ve only used this code with the specific problem I was facing, I&#8217;m sure there are issues with it, I haven&#8217;t tested it comprehensively, YMMV. For example I know it doesn&#8217;t handle arrays very well, particularly those with multiple dimensions.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[The Perils of Consulting - Part 1]]></title>
<link>http://technodave.wordpress.com/2009/08/15/the-perils-of-consulting-part-1/</link>
<pubDate>Sat, 15 Aug 2009 02:38:47 +0000</pubDate>
<dc:creator>David Cornelson</dc:creator>
<guid>http://technodave.wordpress.com/2009/08/15/the-perils-of-consulting-part-1/</guid>
<description><![CDATA[In November of 2008, I was winding up a project at Insurance Auto Auctions. The project had gone ext]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>In November of 2008, I was winding up a project at <a title="Insurance Auto Auctions" href="http://www.iaai.com" target="_blank">Insurance Auto Auctions</a>. The project had gone extremely well and I was walking out with a letter from a director on how satisfied they were with my work. Over the course of ten months, I made increment changes to their development practices. They already had a very mature and strong development environment that included all the necessary hardware and software. No architect or developer could ever say that they weren&#8217;t given the tools at Insurance Auto Auctions.</p>
<p>After convincing management that we needed a dedicated build server, the first thing I implemented was a set of middle-ware templates that acted as a framework for accessing their databases. Not as robust as nHibernate or any of the common frameworks, but tooled for their environment without all of the extra features that either confuse developers or entangle projects with needless work. For instance, the templates I use do not have relations built-in. You have to wire them up on your own. For most traditional CRUD development projects, you rarely need more than <a title="Table Module Design Pattern" href="http://martinfowler.com/eaaCatalog/tableModule.html" target="_blank">Fowler&#8217;s Table Module enterprise design pattern</a> anyway.</p>
<p>The second step was to implement continuous integration using <a title="Cruise Control.NET" href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET" target="_blank">Cruise Control .NET</a>. A fairly common tool in the development world, created by Martin Fowler&#8217;s Thoughtworks consulting firm. This gave us immediate feedback on checked in code.</p>
<p>Thirdly, we went round and round about how to build the new system. Did we want to use traditional WebForms? We&#8217;re we okay with using the beta of ASP.NET MVC? Did we want to role our own MVP (Model View Presenter) framework or possibly do something else? In the end, we decided the simplest implementation, for various reasons, was to create a home grown MVP framework. Of course MVP is considered obsolete now and we saw what people were recommending, but we moved forward anyway. We felt the ability to cleanly write unit tests was a critical aspect. The downside of course was that we had to rewrite a number of HTML controls that come out of the box in ASP.NET. The out of box controls use ViewState and with ViewState off, we had to go it alone, so to speak. Luckily we had Cliff on the team. Any team that has some has brilliant as Cliff should feel blessed. I&#8217;m a pretty smart guy, but more suited to larger problem solving. Cliff has a knack for needling through really fiddly problems with a very elegant solution.</p>
<p>We of course got buy-in to implement unit tests in Visual Studio .NET 2008 Team Test. We installed this on the build server and after every check-in, all tests were executed and the build failed if any tests failed.</p>
<p>The business side worked on user stories, the developers had meetings to gain an understanding of each story, and the rest they say, is history. the development went very smoothly. By implementing all of the code in a single solution and by also implementing a nifty web.config connection string locator, we were able to execute deployments with the built-in Publish feature in Visual Studio. After dealing with complex and error prone deployment processes in the past, the project manager was deleriously happy with the new process.</p>
<p>We deployed the web application to several servers in a farm and after some fairly minor performance tuning, the system was deemed stable and in production.</p>
<p>In the last few weeks of the project, I was also working on securing my next position. This proved to be a very important decision and one that seemed too good to be true. Alas, that old saying is only the tip of the iceberg and will be discussed in Part 2.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Creating a light-weight Data Access Layer in C# (5)]]></title>
<link>http://devio.wordpress.com/2009/08/04/creating-a-light-weight-data-access-layer-in-c-5/</link>
<pubDate>Tue, 04 Aug 2009 12:39:58 +0000</pubDate>
<dc:creator>devio</dc:creator>
<guid>http://devio.wordpress.com/2009/08/04/creating-a-light-weight-data-access-layer-in-c-5/</guid>
<description><![CDATA[Part 1: Retrieve information on tables and columns Part 2: SELECT record, access record fields Part ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Part 1: <a href="http://devio.wordpress.com/2009/07/27/creating-a-light-weight-data-access-layer-in-c-1/" target="_blank">Retrieve information on tables and columns</a></p>
<p>Part 2: <a href="http://devio.wordpress.com/2009/07/28/creating-a-light-weight-data-access-layer-in-c-2/" target="_blank">SELECT record, access record fields</a></p>
<p>Part 3: <a href="http://devio.wordpress.com/2009/07/29/creating-a-light-weight-data-access-layer-in-c-3/" target="_blank">SELECT records, INSERT</a></p>
<p>Part 4: <a href="http://devio.wordpress.com/2009/07/30/creating-a-light-weight-data-access-layer-in-c-4/" target="_blank">Generating C# classes</a></p>
<p>Part 5: Generated C# classes and polymorphism</p>
<p>The code presented in the previous articles generates a C# class definition (based on <a href="http://devio.wordpress.com/category/dbscript/" target="_blank">dbscript</a>&#8217;s Object table) like this:</p>
<pre>public partial class Object : DAL.BaseTable
{
  public Object() { }
  public Object(IDataReader dr) : base(dr) { }
  protected override string TableName { get { return "Object"; } }
  public int OID
  { get { return GetColumnValue&#60;int&#62;(Columns.OID); } }
  public int PV_OID
  {
    get { return GetColumnValue&#60;int&#62;(Columns.PV_OID); }
    set { SetColumnValue(Columns.PV_OID, value); }
  }
  ....
  protected override string IdentityColumn { get { return "OID"; } }
  public static class Columns
  {
    public static string OID = "OID";
    public static string PV_OID = "PV_OID";
    ....
  }
  public static List&#60;Object&#62; GetRecords(IDataReader dr)
  { return GetRecords&#60;Object&#62;(dr); }
  public static List&#60;Object&#62; GetRecords(SqlConnection conn, string sSelect)
  { return GetRecords&#60;Object&#62;(conn, sSelect); }
}</pre>
<p>Note that the class is generated as a partial class, so you are free to extend it in your own code.</p>
<p>In the dbscript database, all information about schema objects is stored in the Object table, and of course, not all columns of this table are used by the different object types, such as tables, views, etc. If we take into account different database engines (a concept <a href="http://devio.wordpress.com/2009/06/10/documenting-oracle-databases/" target="_blank">introduced in dbscript 0.96</a>), then tables, views, etc in MSSQL have different properties than their counterparts in Oracle or PostgreSQL.</p>
<p>Time to create some class which are <em>derived </em>from DAL.BaseTable to inherit the DAL mechanisms, but <em>reference </em>the generated DAL.Object columns:</p>
<pre>public class SchemaObject : dbscriptlib.DAL.BaseTable
{
  protected override string TableName { get { return "Object"; } }
  protected override string IdentityColumn { get { return "OID"; } }
  public int OID
  { get { return GetColumnValue&#60;int&#62;(DAL.Object.Columns.OID); } }
  public string OwnerName
  {
    get { return GetColumnValue&#60;string&#62;(DAL.Object.Columns.OwnerName); }
    set { SetColumnValue(DAL.Object.Columns.OwnerName, value); }
  }
  public string ID
  {
    get { return GetColumnValue&#60;string&#62;(DAL.Object.Columns.ID); }
    set { SetColumnValue(DAL.Object.Columns.ID, value); }
  }
  ....
}
public class Table : SchemaObject
{
  public string FileGroupName
  {
    get { return GetColumnValue&#60;string&#62;(DAL.Object.Columns.FileGroupName); }
    set { SetColumnValue(DAL.Object.Columns.FileGroupName, value); }
  }
  ....
}</pre>
<p>Note that the FileGroupName is defined only for tables, rather than for all DAL classes. In Oracle, there is no FileGroupName, but a TablespaceName, which we map to the original column using this definition:</p>
<pre>public class OracleTable : SchemaObject
{
  public string TablespaceName
  {
    get { return GetColumnValue&#60;string&#62;(DAL.Object.Columns.FileGroupName); }
    set { SetColumnValue(DAL.Object.Columns.FileGroupName, value); }
  }
  ....
}</pre>
<p>With this simple mechanism, a sort of polymorphic table can easily be implemented, and only the accessing classes &#8220;know&#8221; how about the mapping of the table columns.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Cool in VS2010 Beta1: Preprocessed Text Templates]]></title>
<link>http://lessisthenewmore.wordpress.com/2009/08/02/cool-in-vs2010-beta1-preprocessed-text-templates/</link>
<pubDate>Sun, 02 Aug 2009 23:09:42 +0000</pubDate>
<dc:creator>fromano</dc:creator>
<guid>http://lessisthenewmore.wordpress.com/2009/08/02/cool-in-vs2010-beta1-preprocessed-text-templates/</guid>
<description><![CDATA[This is a very cool feature in Visual Studio 2010. You are now able to transform a Text Template int]]></description>
<content:encoded><![CDATA[This is a very cool feature in Visual Studio 2010. You are now able to transform a Text Template int]]></content:encoded>
</item>
<item>
<title><![CDATA[Creating a light-weight Data Access Layer in C# (4)]]></title>
<link>http://devio.wordpress.com/2009/07/30/creating-a-light-weight-data-access-layer-in-c-4/</link>
<pubDate>Thu, 30 Jul 2009 07:55:15 +0000</pubDate>
<dc:creator>devio</dc:creator>
<guid>http://devio.wordpress.com/2009/07/30/creating-a-light-weight-data-access-layer-in-c-4/</guid>
<description><![CDATA[Part 1: Retrieve information on tables and columns Part 2: SELECT record, access record fields Part ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Part 1: <a href="http://devio.wordpress.com/2009/07/27/creating-a-light-weight-data-access-layer-in-c-1/" target="_blank">Retrieve information on tables and columns</a></p>
<p>Part 2: <a href="http://devio.wordpress.com/2009/07/28/creating-a-light-weight-data-access-layer-in-c-2/" target="_blank">SELECT record, access record fields</a></p>
<p>Part 3: <a href="http://devio.wordpress.com/2009/07/29/creating-a-light-weight-data-access-layer-in-c-3/" target="_blank">SELECT records, INSERT</a></p>
<p>As we have the base class of our DAL almost complete, it&#8217;s time to generate the actual table access classes.</p>
<pre>CREATE PROCEDURE Generate_DAL AS
PRINT
'using System;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
/*
 Class Definition for Data Access Layer
 automatically generated by Generate_DAL
 ' + CONVERT(VARCHAR, GETDATE(), 120) + '
*/
namespace DAL
{'
DECLARE @OID INT, @ID VARCHAR(50)
DECLARE cTable CURSOR LOCAL READ_ONLY FORWARD_ONLY FOR</pre>
<p>(insert the <a href="http://devio.wordpress.com/2009/07/27/creating-a-light-weight-data-access-layer-in-c-1/" target="_blank">table SELECT</a> statement here). First we generate the access class constructors:</p>
<pre>OPEN cTable
FETCH cTable INTO @OID, @ID
WHILE @@FETCH_STATUS=0 BEGIN
  IF UPPER(@ID) = 'COLUMNS' SET @ID = SUBSTRING(@ID, 1, LEN(@ID)-1)
  PRINT
'    public partial class ' + @ID + ' : DAL.BaseTable
 {
 public ' + @ID + '() { }
 public ' + @ID + '(IDataReader dr)  : base(dr)  { }
 protected override string TableName { get { return "' + @ID + '"; } }'

DECLARE @colID VARCHAR(50), @colDataType VARCHAR(50), @colLength INT
DECLARE @colNullable BIT, @colIdentity BIT, @colComputed BIT
DECLARE @colNetType VARCHAR(50), @colIdentityName VARCHAR(50)
SET @colIdentityName = NULL
DECLARE cCol CURSOR LOCAL READ_ONLY FORWARD_ONLY FOR</pre>
<p>(insert the <a href="http://devio.wordpress.com/2009/07/27/creating-a-light-weight-data-access-layer-in-c-1/" target="_blank">column SELECT</a> statement here). We need to convert SQL data types to C# data types, and translate NULLable to Nullable&#60;&#62;:</p>
<pre>OPEN cCol
FETCH cCol INTO @colID, @colDataType, @colLength, @colNullable, @colIdentity, @colComputed
WHILE @@FETCH_STATUS=0 BEGIN
  IF @colNullable = 1
    SELECT @colNetType = CASE @colDataType
      WHEN 'int' THEN 'int?'
      WHEN 'bit' THEN 'bool?'
      WHEN 'nvarchar' THEN 'string'
      WHEN 'varchar' THEN 'string'
      WHEN 'ntext' THEN 'string'
      WHEN 'text' THEN 'string'
      WHEN 'datetime' THEN 'DateTime?'
      ELSE @colDataType
    END
  ELSE
    SELECT @colNetType = CASE @colDataType
      WHEN 'int' THEN 'int'
      WHEN 'bit' THEN 'bool'
      WHEN 'nvarchar' THEN 'string'
      WHEN 'varchar' THEN 'string'
      WHEN 'ntext' THEN 'string'
      WHEN 'text' THEN 'string'
      WHEN 'datetime' THEN 'DateTime'
      ELSE @colDataType
    END

  IF @colIdentity = 1 SET @colIdentityName = @colID
  PRINT ' public ' + @colNetType + ' ' + @colID + '{
get { return GetColumnValue&#60;' + @colNetType + '&#62;(Columns.' + @colID + '); }'
  IF @colIdentity = 0 AND @colComputed = 0
    PRINT ' set { SetColumnValue(Columns.' + @colID + ', value); }'
  PRINT ' }'
  FETCH cCol INTO @colID, @colDataType, @colLength, @colNullable, @colIdentity, @colComputed
END
CLOSE cCol

IF @colIdentityName IS NOT NULL
  PRINT '        protected override string IdentityColumn { get { return "' + @colIdentityName + '"; } }'
PRINT '        public static class Columns {'
OPEN cCol
FETCH cCol INTO @colID, @colDataType, @colLength, @colNullable, @colIdentity, @colComputed
WHILE @@FETCH_STATUS=0 BEGIN
  PRINT    '            public static string ' + @colID + ' = "' + @colID + '";';
  FETCH cCol INTO @colID, @colDataType, @colLength, @colNullable, @colIdentity, @colComputed
END
CLOSE cCol
DEALLOCATE cCol
PRINT    '        }'
PRINT    '        public List&#60;' + @ID + '&#62; GetRecords(IDataReader dr) {
    return GetRecords&#60;' + @ID + '&#62;(dr);
  }
public List&#60;' + @ID + '&#62; GetRecords(SqlConnection conn, string sSelect) {
    return GetRecords&#60;' + @ID + '&#62;(conn, sSelect);
  }
}'

FETCH cTable INTO @OID, @ID
END
PRINT    '}'</pre>
<p>The resulting class definition has typed getter/setter properties for each column of the base table, and a static string array containing the names of the table columns.</p>
<p>Thus changes the data model (column type, column name, dropped table or column) are immediately reflected in the generated code, and automatically raise to compilation warnings or errors in your code which depends on the model.</p>
<pre></pre>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[ Creating a light-weight Data Access Layer in C# (3)]]></title>
<link>http://devio.wordpress.com/2009/07/29/creating-a-light-weight-data-access-layer-in-c-3/</link>
<pubDate>Wed, 29 Jul 2009 08:16:48 +0000</pubDate>
<dc:creator>devio</dc:creator>
<guid>http://devio.wordpress.com/2009/07/29/creating-a-light-weight-data-access-layer-in-c-3/</guid>
<description><![CDATA[Part 1: Retrieve information on tables and columns Part 2: SELECT record, access record fields To se]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Part 1: <a href="http://devio.wordpress.com/2009/07/27/creating-a-light-weight-data-access-layer-in-c-1/" target="_blank">Retrieve information on tables and columns</a></p>
<p>Part 2: <a href="http://devio.wordpress.com/2009/07/28/creating-a-light-weight-data-access-layer-in-c-2/" target="_blank">SELECT record, access record fields</a></p>
<p>To select multiple records and create their DAL objects, we pass an IDataReader object or a combination of connection and SELECT statement to a static method GetRecords() and receive a typed List&#60;&#62; of records:</p>
<pre>protected static List&#60;T&#62; GetRecords&#60;T&#62;(IDataReader dr)
    where T : BaseTable, new()
{
  List&#60;T&#62; li = new List&#60;T&#62;();
  while (dr.Read())
  {
    T record = new T();
    record.GetRecord(dr);
    li.Add(record);
  }
  dr.Close();
  return li;
}

protected static List&#60;T&#62; GetRecords&#60;T&#62;(SqlConnection conn, string sSelect)
    where T : BaseTable, new()
{
  SqlCommand cmd = new SqlCommand(sSelect, conn);
  return GetRecords&#60;T&#62;(cmd.ExecuteReader());
}</pre>
<p>The Save() method writes all values of dictNew as INSERT or UPDATE statement:</p>
<pre>public void Save(SqlConnection conn)
{
  if (dictNew == null)
    return;

  if (dictRecord == null)
    Insert(conn);
  else
    Update(conn);
}</pre>
<p>This is a sample implementation of the Insert() command. Note that in the simplest version, the values of dictNew are INSERTed, and only the IDENTITY column (if defined) is retrieved after the insert.</p>
<p>In more complex scenarios, you would want to retrieve all the values of the newly generated record to handle defaults and computed columns. If the table is lacking an IDENTITY column, the record needs to be selected using the columns of a UNIQUE constraint. These scenarios are not covered right now.</p>
<pre>private void Insert(SqlConnection conn)
{
  StringBuilder sb = new StringBuilder();
  sb.Append("INSERT INTO " + TableName + " (");

  bool bFirst = true;
  foreach (string s in dictNew.Keys)
  {
    if (!bFirst)
      sb.Append(", ");
    sb.Append(s);
    bFirst = false;
  }

  sb.Append(") VALUES (");
  bFirst = true;
  foreach (string s in dictNew.Keys)
  {
    if (!bFirst)
      sb.Append(", ");
    sb.Append("@" + s);
    bFirst = false;
  }
  sb.Append(")");

  SqlCommand cmd = new SqlCommand();
  cmd.Connection = conn;

  foreach (string s in dictNew.Keys)
  {
    if (dictNew[s] == null)
      cmd.Parameters.AddWithValue("@" + s, DBNull.Value);
    else
      cmd.Parameters.AddWithValue("@" + s, dictNew[s]);
  }

  if (IdentityColumn != null)
  {
    sb.Append("; SELECT " + IdentityColumn + " FROM " + TableName +
      " WHERE " + IdentityColumn + " = SCOPE_IDENTITY()");
    cmd.CommandText = sb.ToString();
    object oIdentity = cmd.ExecuteScalar();
    dictNew.Add(IdentityColumn, oIdentity);
  }
  else
  {
    cmd.CommandText = sb.ToString();
    cmd.ExecuteNonQuery();
  }
}</pre>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Creating a light-weight Data Access Layer in C# (2)]]></title>
<link>http://devio.wordpress.com/2009/07/28/creating-a-light-weight-data-access-layer-in-c-2/</link>
<pubDate>Tue, 28 Jul 2009 10:09:06 +0000</pubDate>
<dc:creator>devio</dc:creator>
<guid>http://devio.wordpress.com/2009/07/28/creating-a-light-weight-data-access-layer-in-c-2/</guid>
<description><![CDATA[The first part of this series dealt with the queries to retrieve the necessary information on tables]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>The <a href="http://devio.wordpress.com/2009/07/27/creating-a-light-weight-data-access-layer-in-c-1/" target="_blank">first part</a> of this series dealt with the queries to retrieve the necessary information on tables and columns from the system catalog of a SQL Server 2000/2005 database.</p>
<p>Next we need a base class with minimum functionality to provide table name column names, and SELECT, INSERT and UPDATE statements.</p>
<pre>namespace DAL
{
  public abstract class BaseTable
  {
    protected abstract string TableName { get; }
    protected virtual string IdentityColumn { get { return null; } }

    private Dictionary&#60;string, object&#62; dictRecord = null;
    private Dictionary&#60;string, object&#62; dictNew = null;</pre>
<p>dictRecord holds the current (old) values as retrieved by SELECT, dictNew contains new values for INSERT or UPDATE.</p>
<p>The parameterless constructor creates a new record, whereas dictRecord is set by a constructor with IDataReader parameter:</p>
<pre>protected BaseTable()
{
}

protected BaseTable(IDataReader dr)
{
  GetRecord(dr);
}

private void GetRecord(IDataReader dr)
{
  if (dictRecord == null)
  {
    dictRecord = new Dictionary&#60;string, object&#62;();
    for (int iField = 0; iField &#60; dr.FieldCount; iField++)
      if (dr.IsDBNull(iField))
        dictRecord.Add(dr.GetName(iField), null);
      else
        dictRecord.Add(dr.GetName(iField), dr.GetValue(iField));
  }
}</pre>
<p>The generic method GetColumnValue retrieves a (typed) field value from one of the dictionaries, the method SetColumnValue sets a field value in dictNew:</p>
<pre>protected CT GetColumnValue&#60;CT&#62;(string sColumnName)
{
  if (dictNew != null &#38;&#38; dictNew.ContainsKey(sColumnName))
    return (CT)dictNew[sColumnName];

  if (dictRecord != null &#38;&#38; dictRecord.ContainsKey(sColumnName))
    return (CT)dictRecord[sColumnName];

  return default(CT);    
}

protected void SetColumnValue(string sColumnName, object oValue)
{
  if (oValue is string &#38;&#38; (oValue as string) == "")
    oValue = null;

  if (dictNew == null)
    dictNew = new Dictionary&#60;string, object&#62;();
  if (dictNew.ContainsKey(sColumnName))
    dictNew[sColumnName] = oValue;
  else
    dictNew.Add(sColumnName, oValue);
}</pre>
</div>]]></content:encoded>
</item>

</channel>
</rss>
