Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Code generation tools such as those used in O/RM solutions can build the classes for you (these are called many things, but I call them Models). </p> <p>It's not entirely clear what you need (having read your comments as well), but you can use these tools to build whatever it is, not just models. You can build classes that contain lists of field / property associations, or database schema flags, such as "Field X &lt;--> Primary Key Flag", etc. </p> <p>There are some out there already, but if you want to build an entire O/RM yourself, you can (I did). But that is a much bigger question :) It generally involves adding the generation of code which knows how to query, insert, delete and update your models in the database (called CRUD methods). It's not hard to do, but then you take away your ability to integrate with Delphi's data controls and you'll have to work out a solution for that. Although you don't have to generate CRUD methods, the CRUD support is needed to fully eliminate the need for manual changes to adapt to database schema changes later on.</p> <p>One of your comments indicated you want to do some schema querying without using the database connection. Is that right? I do this in my models by decorating them with attributes that I can query at runtime. This requires Delphi 2010 and its new RTTI. For example:</p> <pre><code>[TPrimaryKey] [TField('EmployeeID', TFieldType.Integer)] property EmployeeID: integer read GetEmployeeID write SetEmployeeID; </code></pre> <p>Using RTTI, I can take an instance of a model and ask which field represents the primary key by looking for the one that has the TPrimaryKeyAttribute attribute. Using the TField attribute above provides a link between the property and a database field where they do not have to have the same name. It could even provide a conversion class as a parameter, so that they need not have the same type. There are many possibilities.</p> <p>I use MyGeneration and write my own templates for this. It's easy and opens up a whole world of possibilities for you, even outside of O/RM.</p> <p>MyGeneration (free code generation tool) <a href="http://www.mygenerationsoftware.com/" rel="nofollow">http://www.mygenerationsoftware.com/</a> http://sourceforge.net/projects/mygeneration/</p> <p>MyGeneration tutorial (my blog) <a href="http://interactiveasp.net/blogs/spgilmore/archive/2009/12/03/getting-started-with-mygeneration-a-primer-and-tutorial.aspx" rel="nofollow">http://interactiveasp.net/blogs/spgilmore/archive/2009/12/03/getting-started-with-mygeneration-a-primer-and-tutorial.aspx</a></p> <p>I've taken about 15 mins to write a MyGeneration script that does what you want it to. You'll have to define your Delphi types for the database you're using in the XML, but this script will do the rest. I haven't tested it, and it will probably want to expand it, but it will give you an idea of what you're up against.</p> <pre><code>&lt;%# reference assembly = "System.Text"%&gt;&lt;% public class GeneratedTemplate : DotNetScriptTemplate { public GeneratedTemplate(ZeusContext context) : base(context) {} private string Tab() { return Tab(1); } private string Tab(int tabCount) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); for (int j = 0; j &lt; 1; j++) sb.Append(" "); // Two spaces return sb.ToString(); } //--------------------------------------------------- // Render() is where you want to write your logic //--------------------------------------------------- public override void Render() { IDatabase db = MyMeta.Databases[0]; %&gt;unit ModelsUnit; interface uses SysUtils; type &lt;% foreach (ITable table in db.Tables) { %&gt; &lt;%=Tab()%&gt;T&lt;%=table.Name%&gt;Model = class(TObject) &lt;%=Tab()%&gt;protected &lt;% foreach (IColumn col in table.Columns) { %&gt;&lt;%=Tab()%&gt;&lt;%=Tab()%&gt;f&lt;%=col.Name%&gt;: &lt;%=col.LanguageType%&gt;; &lt;% }%&gt; &lt;%=Tab()%&gt;public &lt;% foreach (IColumn col in table.Columns) { %&gt;&lt;%=Tab()%&gt;&lt;%=Tab()%&gt;property &lt;%=col.Name%&gt;: &lt;%=col.LanguageType%&gt; read f&lt;%=col.Name%&gt; write f&lt;%=col.Name%&gt;; &lt;% }%&gt; &lt;%=Tab()%&gt;&lt;%=Tab()%&gt; &lt;%=Tab()%&gt;end;&lt;% } %&gt; implementation end. &lt;% } } %&gt; </code></pre> <p>Here is one of the table classes that was generated by the script above:</p> <pre><code>TLOCATIONModel = class(TObject) protected fLOCATIONID: integer; fCITY: string; fPROVINCE: string; public property LOCATIONID: integer read fLOCATIONID write fLOCATIONID; property CITY: string read fCITY write fCITY; property PROVINCE: string read fPROVINCE write fPROVINCE; end; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload