<?xml version="1.0" encoding="utf-8"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title>Actian Community Forums - Blogs</title>
		<link>http://community.actian.com/forum/blogs/</link>
		<description><![CDATA[Actian Corporation is a leading provider of open source database management software and support services. [Toll Free] +1 (888) 446-4737]]></description>
		<language>en</language>
		<lastBuildDate>Tue, 21 May 2013 20:31:47 GMT</lastBuildDate>
		<generator>vBulletin</generator>
		<ttl>60</ttl>
		<image>
			<url>http://community.actian.com/forum/ingres4/misc/rss.jpg</url>
			<title>Actian Community Forums - Blogs</title>
			<link>http://community.actian.com/forum/blogs/</link>
		</image>
		<item>
			<title>Want to learn more about OpenROAD and see what the team is up to?</title>
			<link>http://community.actian.com/forum/blogs/teresa/133-want-learn-more-about-openroad-see-what-team-up.html</link>
			<pubDate>Fri, 17 May 2013 15:13:11 GMT</pubDate>
			<description>Several members of the OpenROAD Engineering team will be running a code Sprint at the Thistle City Barbican hotel in London on June 8th, 9th, and...</description>
			<content:encoded><![CDATA[<div>Several members of the OpenROAD Engineering team will be running a code Sprint at the Thistle City Barbican hotel in London on June 8th, 9th, and half day on the 10th followed by the UK AUA 1-daytechnical  conference on June 11th, at which there will be several OpenROAD Specific presentations.<br />
<br />
<b>Join the OpenROAD Sprint June 8th - 10th in London </b><br />
Sprint projects tend to be 4GL projects as they can be implemented quickly.  How do we determine the projects implemented at a sprint? We propose items to the attendees based on the following:<ul><li>Review enhancements submitted via the Idea Center (previously Service Desk) for ideas that can be implemented in a reasonable timeframe</li>
<li>Other Projects we’ve documented at <a href="http://community.actian.com/wiki/OpenROAD_Sprint_Projects" target="_blank">OpenROAD Sprint Projects - Ingres Community Wiki</a></li>
<li>Reported low priority bugs that are good training candidates for the sprint attendees</li>
<li>Enhancements that are important to the Sprint attendees, for example, <a href="http://community.actian.com/wiki/Ingres_OpenROAD_Projects/Add_ToolTextTip_attribute_to_BitmapObject_class" target="_blank">Ingres OpenROAD Projects/Add ToolTextTip attribute to BitmapObject class - Ingres Community Wiki</a></li>
<li>Improving information on using OpenROAD <ul><li>Composing “How To” articles that should be added to the documentation or written up as a blog entry (Note, we will gladly accept any contributions that you may want to write up and submit to <a href="mailto:teresa.king@actian.com">us</a> prefer not to go through the hassle of putting together a blog entry yourself)</li>
<li>Improving areas of the documentation that are unclear to the attendees</li>
</ul></li>
<li>Other items raised by the Sprint attendees</li>
</ul><br />
Attending and participating in an OpenROAD sprint provides an opportunity to get a feature implemented that you’ve long wanted or fix a particularly annoying bug that is more of an annoyance than a showstopper. Past events have seen a number of features either released as part of OpenROAD 5.1 or 6.0 or targeted for the upcoming release.  For more information on the sprint projects targeted for the next major OpenROAD release see <a href="http://community.actian.com/forum/blogs/teresa/85-accomplishments-openroad-sprint-2011-uk-iua.html" target="_blank">http://community.actian.com/forum/bl...11-uk-iua.html</a> and <a href="http://community.actian.com/forum/blogs/teresa/118-accomplishments-openroad-sprint-2012-german-iua-giua.html" target="_blank">http://community.actian.com/forum/bl...-iua-giua.html</a>. <br />
<br />
<b>Attend the UK AUA June 11th in London</b><br />
After the Sprint, join the OpenROAD team at the UK AUA on Tues June 11th at the Thistle City Barbican hotel in London.  The UK AUA is a great opportunity to learn more about OpenROAD as well as Ingres, Vectorwise, and other products newly added to the Actian portfolio in addition to networking with other customers using the technology. The AUA event is focused on providing great technical information to the attendees.<br />
<br />
There will be four OpenROAD Specific presentations on Tues afternoon including:<ul><li><b>Sneak Peek at OpenROAD 6.2's Sprites - Can it be that easy?</b><br />
Sprites!  What are they trying to do, make OpenROAD into a game development platform?   The answer to that question is no, but sprites make it possible to create displays previously considered impossible with OpenROAD.  Join us for an in-depth look at some new user classes that allow you work with small actionable graphic elements.  See for yourself how this can revolutionize your existing applications, and imagine the possibilities for new initiatives.    After this sneak peek at OpenROAD Sprites you will be able to answer for yourself this question: Can it be that easy?</li>
<li><b>Cats and Dogs – How to domesticate list-handling to obey your application’s every whim</b><br />
To handle sets of business items, OpenROAD provides you with two representations: customized and type specific Arrays (cats);  and dynamic, optimized, generically structured ChoiceLists (dogs). Cats and dogs are complementary: cats provide focused browsing and editing via TableFields; dogs provide at-a-glance selection via five different types of ChoiceField; between them they cover the range of multi-item handling that most applications require.<br />
<br />
To get the best results, dogs in particular must be approached in the right way. This presentation begins with a common requirement – how to provide row-specific dropdown lists in TableFields – to illustrate some key techniques; then follows with advanced techniques for building lists from a range of source types (database, files, datastrings, arrays, master-lists). The session will also give you the opportunity to raise and discuss other list-handling issues you may have, so come prepared!</li>
<li><b>Don’t call us, we’ll call you<br />
Revealing the mysteries of the XMLParserCallbacks class</b><br />
<br />
This session provides an in-depth view of the new feature of the upcoming OpenROAD release.<br />
It will answer a series of questions, e.g.:<ul><li>What is a callback?</li>
<li>What are XML parser callbacks useful for?</li>
<li>When does the XML parser call what?</li>
<li>How to define a callback procedure?</li>
<li>What does a callback procedure cannot do?</li>
<li>How to tell the parser which procedures should be called when?</li>
</ul>The session will also provide several usage examples, e.g.:<ul><li>Abort parsing after getting the information required.</li>
<li>Prevent memory overflow by discarding parsed elements.</li>
<li>Loading very big XML files into a database.</li>
</ul></li>
<li><b>OpenROAD Status and Roadmap</b><br />
It is an exciting time for OpenROAD developers, with major new features available in the last two releases; OpenROAD 6.0 is seeing a lot of uptake due to the single-byte, multi-byte and Unicode support provided. We are interested in any challenges you may be facing or have faced with the migration to this release so we can continue to improve your OpenROAD experience.  <br />
<br />
The next release of OpenROAD provides graphical features you can use to enhance the appearance of your applications and improves deployment options.  The feature set of this release is completely defined and nearing completion, but to polish the features you actually use, OpenROAD development must now focus on how to make these powerful features easy to use.  This is a perfect time discuss challenges you face-using OpenROAD, and join us for a lively discussion about product improvements that could help alleviate some of these challenges. Come prepared to participate with your challenges, questions, and OpenROAD needs!</li>
</ul><br />
<b>Highlights of the General Sessions:</b><ul><li>Keynote from Mike Hoskins</li>
<li>Product Roadmap Overview from Mark Milani</li>
<li>Ingres and OpenROAD Update from Emma McGrattan</li>
<li>And several others</li>
</ul><br />
In addition, there will be presentations specific to Ingres, Vectorwise, and new additions to the Actian Portfolio.  See <a href="http://www.uk-iua.org.uk/node/4" target="_blank">Join the UK AUA and Attend the 2013 Conference | UK Actian Users Association</a> for the provisional agenda. It’s not too late to register, see <a href="http://www.regonline.co.uk/ukiua2013" target="_blank">http://www.regonline.co.uk/ukiua2013</a>.</div>

]]></content:encoded>
			<dc:creator>teresa</dc:creator>
			<dc:publisher>26</dc:publisher>
			<guid isPermaLink="true">http://community.actian.com/forum/blogs/teresa/133-want-learn-more-about-openroad-see-what-team-up.html</guid>
		</item>
		<item>
			<title>On Terminate event block in field scripts</title>
			<link>http://community.actian.com/forum/blogs/teresa/132-terminate-event-block-field-scripts.html</link>
			<pubDate>Fri, 12 Apr 2013 17:57:47 GMT</pubDate>
			<description>On Terminate event is currently valid only in frame scripts. An enhancement request, SIR 122582, for this event to be valid in field scripts is under...</description>
			<content:encoded><![CDATA[<div>On Terminate event is currently valid only in frame scripts. An enhancement request, SIR 122582, for this event to be valid in field scripts is under review for possible inclusion in a future release. In the meantime, an alternative solution is to write a facility in 4GL code that provides equivalent results to this proposed feature, one that even offers a more flexible and complete solution. This article describes alternative ways to implement this solution.<br />
<br />
<b>Problem</b><br />
<br />
OpenROAD allows initialize blocks in field scripts. In these initialize blocks developers can declare variables that are visible (in scope) only for the field’s field script.<br />
<br />
When the frame terminates, there is no terminate block available in field scripts that is equivalent to a frame script terminate block, yet you may need to access the field-local variables to perform local cleanup, state checking, or value finalization of some kind. For example, if the variable type is a userclass, you may need to call some methods when a frame closes.<br />
<br />
This is a useful feature, and provision of such a capability is under review for a future release. However, two additional considerations to look at are:<ul><li> Frame open and frame close are not the only critical state-changes that may require local access and local response, particularly if the application is using generically coded field templates. State changes such as field resize, open/switch/save business object, change focus (between panels), change access mode, and call-return may all benefit from local access and local response.</li>
<li> Until the “local terminate blocks” feature is implemented, there is a solution already available that gives equivalent results and offers a more flexible and complete response (see Resolution).</li>
</ul><br />
<b>Resolution</b><br />
<br />
Field-local procedures can always be invoked from anywhere in the frame (including from a terminate event block) by their prochandles. The following two statements are equivalent if the prochandle and procedurename in this example both refer to the same procedure:<br />
<blockquote>returnvalue = prochandle.Call(…parameters…);<br />
returnvalue = callproc procedurename(…parameters…);</blockquote>There are three possible 4GL solutions to this problem:<br />
<br />
<b>Option 1:</b> Put the identical code that you planned to use in a field-local terminate block into a field-local <i>onclose</i> procedure instead, with a frame-local variable referencing that procedure's prochandle. The frame-local terminate code can then invoke it by a single-line call before continuing its own processing. It can also inspect and respond to a return value—something not possible in event block processing without awkward status-variable management. The Notes section below offers additional considerations to this first option.<br />
<br />
<b>Option 2:</b> Have a frame-local variable reference an array that contains prochandles for each field's onclose procedure. This approach has the advantage that it does not require that the frame-local terminate code be aware of which fields have this terminate code. Then it can run as follows:<br />
<blockquote>for i = 1 to oncloses.LastRow do<blockquote>prochandle = oncloses[i];<br />
returnvalue = prochandle.Call();</blockquote>endfor;</blockquote>The Implementation section describes a straightforward example of this second option.<br />
<br />
<b>Option 3:</b> Use a StringHashTable that a frame-local variable references to store the prochandles, keying each entry with a text string that identifies which state-change invokes it. You can store each prochandle as many times as there are state-changes that invoke it. Then you can handle <i>all</i> the frame's state-changes—not just the <i>onclose</i> state-change—through a single simple mechanism. That mechanism uses the StringHashTable’s FindAll() method to collect all prochandles with the same state-change key, ready to have the option 2 code applied to them:<br />
<blockquote>prochashtable.FindAll(key='onclose', results=oncloses);</blockquote>This third option is the most generic approach to handling all field script code that you want to execute when a frame terminates. It is a bit more complex because it builds on the second option techniques.<br />
<br />
What these approaches do not offer is the ability to avoid a frame-close that a resume from a local terminate event block offers. However, if the onclose procedures are invoked from the windowclose event instead of from the terminate event, a resume statement within the procedures will work as desired.<br />
<br />
<b>Implementation</b><br />
<br />
This implementation confines itself to option 2, since it directly addresses the particular topic of this blog article. Note that option 3, although more complex, offers more power and flexibility across a wider range of requirements.<br />
<br />
For each field script that requires &quot;on terminate&quot; processing:<ol style="list-style-type: decimal"><li> Write the field script &quot;on terminate&quot; event block exactly as if the local terminates feature exists.</li>
<li> Convert the &quot;on terminate =&quot; text to &quot;procedure onclose =&quot;</li>
<li> Adjust any frame-return or openframe invocations in the procedure (see Notes).</li>
<li> In the field-local initialize block, add the following line of code, which inserts each procedure in turn at row 1, so that last initialized is first closed:</li>
</ol><blockquote>oncloses.InsertRow(<br />
rowobject=curscriptscope.GetProcHandle(name='onclo  se'));</blockquote>In the frame initialize block, add the following declaration:<br />
<blockquote>oncloses = array of ProcHandle;</blockquote>In the frame terminate (or windowclose) block, declare the prochandle and returnvalue variables and write the following code, adjusting the response to the returnvalue to suit your needs:<br />
<blockquote>for i = 1 to oncloses.LastRow do<blockquote>prochandle = oncloses[i];<br />
returnvalue = prochandle.Call();<br />
if returnvalue = &lt;DO_NOT_CLOSE&gt; then<blockquote>    resume;</blockquote>endif;</blockquote>endfor;</blockquote><b>Notes</b><br />
<br />
There are two minor caveats with this solution, both unlikely to cause problems in the context of a frame close:<ul><li> If the procedure issues an openframe statement, it must explicitly include “with parentframe=curframe” in the statement.</li>
<li> If the procedure wants to force an immediate frame close, it cannot simply issue return, as a terminate block would. In the context under discussion, returning a &quot;close now&quot; returncode for the calling event block to act on would work.</li>
</ul><br />
This article was contributed by Sean Thrower from OpenROAD Engineering.</div>

]]></content:encoded>
			<dc:creator>teresa</dc:creator>
			<dc:publisher>26</dc:publisher>
			<guid isPermaLink="true">http://community.actian.com/forum/blogs/teresa/132-terminate-event-block-field-scripts.html</guid>
		</item>
		<item>
			<title>Surrogate Keys: Part 5, Pitfalls, Booby-Traps and the 1970s Resurrected</title>
			<link>http://community.actian.com/forum/blogs/rhann/131-surrogate-keys-part-5-pitfalls-booby-traps-1970s-resurrected.html</link>
			<pubDate>Fri, 05 Apr 2013 11:04:51 GMT</pubDate>
			<description><![CDATA[I'm almost finished ranting.  For now. 
 
So far I've shown that being scared of natural keys is about as grown-up and professional as being scared...]]></description>
			<content:encoded><![CDATA[<div>I'm almost finished ranting.  For now.<br />
<br />
So far I've shown that being scared of natural keys is about as grown-up and professional as being scared of balloon animals.  I still need to show why properly diligent database designers must actively shun surrogate keys until they are absolutely unavoidable.<br />
<br />
If you skipped Part 2 of this series of postings to get to the &quot;juicy bits&quot; you should go back and <a href="http://community.actian.com/forum/blogs/rhann/127-surrogate-keys-part-2-boring-bit.html" target="_blank">read it now</a>.  <br />
<br />
I've already established the very limited cases where a surrogate key is justified. Now I want to look at the booby-trap waiting for those who mechanically use a single surrogate key even when the only natural key is actually composite—and who ever heard of anyone deliberately introducing a composite surrogate key?<br />
<br />
Imagine an application to study air transport service quality.  Amongst other things we are interested in routes operated by airlines between airports; the aircraft used on those routes, and (completed) flights.  (We are not interested in superfluous details of code shared flights.)<br />
<br />
One obvious design using only natural keys would be this:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="alt2" dir="ltr" style="
		margin: 0px;
		padding: 6px;
		border: 1px inset;
		width: 640px;
		height: 98px;
		text-align: left;
		overflow: auto">CREATE TABLE airlines 
( 
   iata_designator VARCHAR(3) NOT NULL UNIQUE,
   ... 
);</pre>
</div><div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="alt2" dir="ltr" style="
		margin: 0px;
		padding: 6px;
		border: 1px inset;
		width: 640px;
		height: 210px;
		text-align: left;
		overflow: auto">CREATE TABLE routes 
( 
   iata_designator VARCHAR(3) NOT NULL, 
   flight_nr VARCHAR(5) NOT NULL,
   CONSTRAINT distinct_routes 
      UNIQUE (iata_designator, flight_nr), 
   CONSTRAINT route_airline 
      FOREIGN KEY (iata_designator) 
      REFERENCES airlines (iata_designator)
      ON UPDATE CASCADE,
   ... 
);</pre>
</div><div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="alt2" dir="ltr" style="
		margin: 0px;
		padding: 6px;
		border: 1px inset;
		width: 640px;
		height: 210px;
		text-align: left;
		overflow: auto">CREATE TABLE aircraft 
( 
   iata_designator VARCHAR(3) NOT NULL,
   tail_nr VARCHAR(7) NOT NULL,
   CONSTRAINT distinct_aircraft 
      UNIQUE (iata_designator, tail_nr),
   CONSTRAINT aircraft_airline 
      FOREIGN KEY (iata_designator) 
      REFERENCES airlines (iata_designator)
      ON UPDATE CASCADE, 
   ... 
);</pre>
</div><div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="alt2" dir="ltr" style="
		margin: 0px;
		padding: 6px;
		border: 1px inset;
		width: 640px;
		height: 354px;
		text-align: left;
		overflow: auto">CREATE TABLE flights
( 
   iata_designator VARCHAR(3) NOT NULL,
   flight_nr VARCHAR(5) NOT NULL, 
   tail_nr VARCHAR(7) NOT NULL,
   scheduled_date DATE NOT NULL, 
   CONSTRAINT distinct_flights 
      UNIQUE (iata_designator,flight_nr,tail_nr,scheduled_date ),
   CONSTRAINT flight_airline 
      FOREIGN KEY (iata_designator) 
      REFERENCES airlines (iata_designator) 
      ON UPDATE CASCADE, 
   CONSTRAINT flight_route 
      FOREIGN KEY (iata_designator, flight_nr)
      REFERENCES routes (iata_designator, flight_nr)
      ON UPDATE CASCADE,
   CONSTRAINT flight_aircraft FOREIGN KEY (iata_designator, tail_nr)
      REFERENCES aircraft (iata_designator, tail_nr)
      ON UPDATE CASCADE,
   ...
)</pre>
</div>Though I say so myself this is a pretty good schema.  It implements a surprising amount of business logic implicitly, eliminating the need to implement it (and repeatedly re-implement it) explicitly in application code.  It lends itself to writing simple queries to address any conceivable information need. <br />
<br />
Now, what do we get if we follow the advice to use surrogate keys everywhere?  It's hard for me to guess what a person who thinks like that might do but I'm pretty sure this is one good possibility:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="alt2" dir="ltr" style="
		margin: 0px;
		padding: 6px;
		border: 1px inset;
		width: 640px;
		height: 114px;
		text-align: left;
		overflow: auto">CREATE TABLE airlines 
( 
   airline_id INTEGER PRIMARY KEY,
   iata_designator VARCHAR(3) NOT NULL UNIQUE,
   ... 
);</pre>
</div><div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="alt2" dir="ltr" style="
		margin: 0px;
		padding: 6px;
		border: 1px inset;
		width: 640px;
		height: 210px;
		text-align: left;
		overflow: auto">CREATE TABLE routes 
( 
   route_id INTEGER PRIMARY KEY,
   airline_id INTEGER NOT NULL, 
   flight_nr VARCHAR(5) NOT NULL,
   CONSTRAINT distinct_routes 
      UNIQUE (airline_id, flight_nr), 
   CONSTRAINT route_airline 
      FOREIGN KEY (airline_id) 
      REFERENCES airlines,
   ... 
);</pre>
</div><div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="alt2" dir="ltr" style="
		margin: 0px;
		padding: 6px;
		border: 1px inset;
		width: 640px;
		height: 210px;
		text-align: left;
		overflow: auto">CREATE TABLE aircraft 
( 
   aircraft_id INTEGER PRIMARY KEY,
   airline_id INTEGER NOT NULL, 
   tail_nr VARCHAR(7) NOT NULL,
   CONSTRAINT distinct_aircraft 
      UNIQUE (airline_id, tail_nr),
   CONSTRAINT aircraft_airline 
      FOREIGN_KEY (airline_id) 
      REFERENCES airlines, 
   ... 
);</pre>
</div><div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="alt2" dir="ltr" style="
		margin: 0px;
		padding: 6px;
		border: 1px inset;
		width: 640px;
		height: 274px;
		text-align: left;
		overflow: auto">CREATE TABLE flights
( 
   flight_id INTEGER PRIMARY KEY,
   route_id VARCHAR(3) NOT NULL,
   aircraft_id INTEGER NOT NULL,
   scheduled_date DATE NOT NULL, 
   CONSTRAINT distinct_flights 
      UNIQUE (route_id, aircraft_id, scheduled_date ),
   CONSTRAINT flight_route 
      FOREIGN KEY (route_id) 
      REFERENCES routes,
   CONSTRAINT flight_aircraft 
      FOREIGN_KEY (aircraft_id) 
      REFERENCES aircraft,
   ...
)</pre>
</div>Ignore the constraints if they bother you.  They're not relevant to my argument.    <br />
<br />
I certainly see lots of designs like this so I'm confident this isn't just a straw man I'm setting up here.<br />
<br />
Unfortunately this design does not behave like the real world nor like my proposed design above.  It throws away important knowledge that the aircraft and the route flown belong to the same airline.  Worse still, the absence of that information compels the computer and the programmer to assume it is <i>not</i> so—even though it really is.<br />
<br />
Perhaps the designer very optimistically hopes &quot;something else&quot; takes care of that, always and forever; or maybe the designer doesn't even see the problem.  I would worry that having set out with the &quot;managing the containers&quot; mindset which underlies indiscriminate use of surrogate keys the designer would be unlikely to spot the problem.  It would then be up to the application programs (and all future application programs) to enforce the real world logic—assuming the programmers somehow become aware of it. With the design that uses only natural keys it is simply impossible to say a flight was served by the wrong airline's plane. <br />
<br />
So much for simpler programming.  So much for data quality.<br />
<br />
Furthermore a lot of very reasonable queries on the surrogate key design will involve joining tables that weren't previously needed.  <br />
<br />
So much for improved performance. <br />
<br />
Remind me, why are we supposed to use surrogate keys everywhere?<br />
<br />
Sure one could cooper up the design with constraints and horrible database procedures to enforce the real world rules, but we'd end up with a way more complex, non-portable and unweildy design, just to allow us to use the surrogates I say aren't needed in the first place.  <br />
<br />
If this example seems contrived I can give you others.  But it doesn't matter.  The use of surrogate keys here concealed a logical error and that error can happen in any real design.  It does happen in real designs.<br />
<br />
All the other arguments against using surrogate keys: the complexity; the futility, the obfuscation, all build up to a compelling case for avoiding unnecessary surrogate keys.  But this is the knock-out blow.  <br />
<br />
<b>Surrogate keys as they are usually applied subvert the logical integrity of the database. </b><br />
<br />
I have done a lot of ranting now and I'm feeling quite worn out, but I have just one final mini-rant to get off my chest.  The surrogate key disease is reaching whole new levels of stupid.<br />
<br />
I have lately been seeing database &quot;designs&quot; in which natural keys are not just replaced by spurious surrogate keys, but even the surrogates are being replaced by yet-more-spurious surrogates.  I'm not going to go into this in depth but typically what you see is table <b>A</b> has a surrogate key <b>A.id</b>.  The related table <b>B</b> has its own surrogate key <b>B.id</b> and a foreign key referencing <b>A</b> that would have been called <b>id </b>in any sane universe can't be because of <b>B.id</b> so usually it gets renamed something like <b>A_id</b>.  And another related table <b>C</b> has yet another surrogate key <b>C.id</b> and contains a foreign key <b>B_id</b> that references <b>B</b>.  And so on and so on.<br />
<br />
Even if the facts in tables <b>A</b>, <b>B</b> and <b>C</b> depend on the same natural key you can't get at the facts in <b>C</b> even though you know the natural key.  You are forced to trudge from <b>A</b> to <b>B</b> to <b>C</b>.<br />
<br />
This is just implementing an old-fashioned 1970s network database (only much, much worse because it uses the lumbering great SQL engine instead of a lightweight disk access API).  <br />
<br />
Two things about that:<ol style="list-style-type: decimal"><li>surrogate keys are claimed to improve performance and here they are degrading it by requiring unnecessary joins, and</li>
<li> actively concealing the essential logic of the database (by concealing the identity of the facts) forces the programmer to be the optimizer and hard-code the query strategy.</li>
</ol>It's bonkers!  We did that stuff 40 years ago and hated it then.<br />
<br />
Don't get me started on the very similar fetish for encoding everything...<br />
<br />
<font size="3">Conclusions</font><br />
<br />
1. When you have a usable natural key there is no automatic justification for introducing a surrogate key.  Forget the limitations of other products, Ingres likes natural keys.<br />
<br />
2. If you have a natural key but it's genuinely not usable it is OK to introduce a surrogate key, but take care not to accidentally trample over the constraints of the real world.  <br />
<br />
3. If you don't have a natural key you can't use a surrogate to hide the problem.<br />
<br />
The obvious and straightforward way to design a database is the right way to do it.  There is no automatic justification for doing anything else, whether it is called &quot;best practice&quot; or &quot;future-proofing&quot; or whatever.  And when it makes things worse, well <i>that</i> is unprofessional!<br />
<br />
There, I feel better now.</div>

]]></content:encoded>
			<dc:creator>rhann</dc:creator>
			<dc:publisher>131</dc:publisher>
			<guid isPermaLink="true">http://community.actian.com/forum/blogs/rhann/131-surrogate-keys-part-5-pitfalls-booby-traps-1970s-resurrected.html</guid>
		</item>
		<item>
			<title>Surrogate Keys: Part 4, In Search of a Niche</title>
			<link>http://community.actian.com/forum/blogs/rhann/130-surrogate-keys-part-4-search-niche.html</link>
			<pubDate>Thu, 04 Apr 2013 21:35:00 GMT</pubDate>
			<description>In the previous section (http://community.actian.com/forum/blogs/rhann/128-surrogate-keys-part-3-surrogates-composites.html) I showed that natural...</description>
			<content:encoded><![CDATA[<div>In the <a href="http://community.actian.com/forum/blogs/rhann/128-surrogate-keys-part-3-surrogates-composites.html" target="_blank">previous section</a> I showed that natural keys—including composite natural keys—can perform fine.  In my extensive experience they usually do.  <br />
<br />
There are exceptional cases when they don't do so well though, and so a surrogate key is justified.   <br />
<br />
A big VARCHAR key can be a problem when we try to use it as a physical key.  For instance the biggest VARCHAR that can be used as a physical key in an Ingres B-tree is 1,000 characters.  If your key is longer than that you are forced to introduce a surrogate.  <br />
<br />
OK, fine, so what about big VARCHARs smaller than that?<br />
<br />
A fully-qualified file pathname uniquely identifies a file so it's a logical key, but they can be quite long with very little variation in the left-most portion of the pathname. It is reasonable to wonder how well it would perform as a physical key.<br />
<br />
Staying with the pathname example, there are two cases to consider: tables where the pathname is a logical key (i.e. unique values in the table) and tables where it is a foreign key (i.e. potentially many copies of the same value in the table).<br />
<br />
If the pathname is used in only one table, as a logical key, and not as a foreign key in any other table, there is no benefit to having a surrogate for it.  You can't know the surrogate without looking it up (scanning for it) using the natural key, and once you've done that you already have the row you want!  If scanning the table is unacceptable then the solution is to look for a more tractable natural key in the conceptual model.  A surrogate doesn't help.<br />
<br />
Looking at the second case where the pathname is used as a foreign key, possibly recurring many times, a surrogate <i>may </i>be helpful, but it's not clear-cut.<br />
<br />
Two issues seem to make a surrogate look attractive here: wasted space and slow execution.<br />
<br />
So what about wasted space?  If you have related tables and the pathname is the foreign key in a one-to-many relationship, the very long string will be repeated in every row where it is a foreign key—and that could be a lot of rows.<br />
<br />
And what if the key is vastly bigger than the non-key value it identifies, which might be as small as just a single integer (representing, say, the number of times the file has been requested)?<br />
<br />
Such a &quot;waste&quot; of space offends some kind of aesthetic.  It goes against intuitions of efficiency. <br />
<br />
Tough.  Disk space is one thing we really can't afford to spend too much time or complexity to conserve.  Space is practically free today and only getting cheaper. <img src="http://www.rationalcommerce.com/images/hd-cost-graph.png" border="0" alt="" /> <br />
<font size="1">Source: <a href="http://www.mkomo.com/assets/hd-cost-graph.png" target="_blank">http://www.mkomo.com/assets/hd-cost-graph.png</a></font><br />
<br />
The longest VARCHAR column Ingres supports as a B-tree key is less than 1kb.   Let's say we use it all.  At $0.075 per gigabyte for HDD storage today that works out to about .0000075c/key at most.  <br />
<br />
So forget about the cost of disk space; even if we take into account the cost of extra space for multiple &quot;needlessly&quot; bloated checkpoints it is still close enough to free.  <br />
<br />
Of course if you want to use SSD or you want to design a database to fit comfortably into RAM, the cost of space might justify the use of surrogates.  But you still need to do the sums to be sure.  <br />
<br />
If space isn't a concern, how about execution time? How slow is it to compare two big VARCHAR keys when joining tables or doing a lookup with Ingres?  The following graph has the answers.<br />
<img src="http://www.rationalcommerce.com/images/varchar-keys.PNG" border="0" alt="" /><br />
This graph shows the result of a series of benchmarks done on a very, very <a href="http://community.actian.com/forum/blogs/rhann/129-benchmarking.html" target="_blank">low-end machine</a>, using worst-case conditions.<br />
<br />
Two tables were used.  One was a 1 million row table with a big VARCHAR column (the natural key), an integer surrogate key column, and an integer non-key column.  The other was heap of 10,000 randomly selected and shuffled rows from the big table (with both the natural and the surrogate key).   <br />
<br />
A series of four tests were done in each trial: a join between the two tables on the natural key; a join on the surrogate key; 10,000 singleton selects using the natural key, and 10,000 singleton selects using the surrogate key.  The big table was physically MODIFY'd on the key in question for each test.<br />
<br />
Three trials were done, structuring the big table as a hash table, an ISAM table, and then a B-tree.<br />
<br />
There's lots of interesting features in this graph but I'll point out just a few.<br />
<br />
First of all the performance of the hash table (middle graph) was completely insensitive to whether the physical key was the big natural key or the integer surrogate.   On that basis there is just no point ever introducing a surrogate physical key if you intend a table will always be a hash table.   Furthermore, the hash table performed far better than any other structure when using a natural key for random look-ups, with a worst-case access time of about 8.7msec even on the junk hardware I was using.  If your use case predominantly involves look-ups and there is no compelling reason to choose another structure, natural keys in a hash table are the way to go. <br />
<br />
So far I've done a pretty good job of not doing what the title of this posting promised.  This was supposed to be about finding cases where surrogate keys are a net benefit.  I better get on with it.<br />
<br />
The diamond-shaped red dots in the other two graphs show the performance when doing random lookups using a big VARCHAR physical key in an ISAM or B-tree table.  The triangular red dots in the same two graphs show the performance doing random lookups with a surrogate key.  Clearly, as the natural key gets bigger the performance of the surrogate key that replaces it degrades more slowly.  When the natural key is much bigger than about 400 characters I will concede there may be some benefit to using a surrogate—although the difference in response time between a 50 character key and 400 character key is only a footling 4msec, even using junk hardware.  On decent hardware with a key that wasn't designed specifically to perform badly, the difference might not even exist.<br />
<br />
Surrogate keys look most beneficial when joining tables.  The blue dots in the B-tree and ISAM graphs show the response time when joining to an ISAM table or a B-tree table.  The diamond dots show the response time when using a big VARCHAR key and the triangular dots show the response time for the surrogate key.  Surrogates start to pull away from big natural keys when they get to about 600 characters in an ISAM table, and above about 300 characters in a B-tree. <br />
<br />
Glossing over a lot of detail and special cases, boiling it down to a simple one-size-fits-all rule of thumb, <b>physical keys bigger than 300 characters can justifiably be replaced with a surrogate key.</b>  Frankly though, I wouldn't bat an eye if you showed me a table with a key twice that size.<br />
<br />
Another rule of thumb is to assume you can use a natural key until you find out you can't.<br />
<br />
Surrogates are not wholly evil, they are just minimally useful—how many business applications have a 300 character natural key?—and surrogates can lead the unwary designer into making some serious logical errors.  Nor are they free; I've not said much about how they obfuscate the meaning of the database nor how they can easily subvert the integrity of the database.  This posting wasn't meant to be a licence to use them willy-nilly.  It was just acknowledging that sometimes even I need to use one.  In my <a href="http://community.actian.com/forum/blogs/rhann/131-surrogate-keys-part-5-pitfalls-booby-traps-1970s-resurrected.html" target="_blank">next posting</a> I'll show how surrogates can lead us very badly astray.</div>

]]></content:encoded>
			<dc:creator>rhann</dc:creator>
			<dc:publisher>131</dc:publisher>
			<guid isPermaLink="true">http://community.actian.com/forum/blogs/rhann/130-surrogate-keys-part-4-search-niche.html</guid>
		</item>
		<item>
			<title>Surrogate Keys: Part 3, Surrogates for Composites</title>
			<link>http://community.actian.com/forum/blogs/rhann/128-surrogate-keys-part-3-surrogates-composites.html</link>
			<pubDate>Wed, 03 Apr 2013 15:04:00 GMT</pubDate>
			<description>If you made the effort to wade through part 2 of this series you have seen my claim that keys should be simple.  Who could argue? 
 
A simple key is...</description>
			<content:encoded><![CDATA[<div>If you made the effort to wade through part 2 of this series you have seen my claim that keys should be simple.  Who could argue?<br />
<br />
A simple key is one which is easy to use.  It is easy to use if it is easy to think about and it performs well in the physical database.  If the conceptual model leads naturally to a certain physical key in the database, and if the end-users who own the data are familiar and comfortable with it, and if it performs adequately, there is no reason not to use it.  In fact I would say anyone who wants to throw it out and replace it with a newfangled surrogate (which means nothing to anyone) has a very steep hill to climb.  <br />
<br />
This argument still holds if the physical key happens to be composite.  Compactness does not automatically trump familiarity when we are trying to decide what is simple. But speed might.<br />
<br />
It is widely held that composite physical keys perform badly.  We need  to look at the performance of composite physical keys so we can decide when it might be sensible to introduce a surrogate. A composite key consisting of a couple or three columns is probably pretty manageable, but just how many columns is too many? <br />
<br />
I set up a benchmark involving a million row table.  As well as non-key (data) columns it also had a 10-column logical key, and a single column surrogate key.  From this table I sampled 10,000 keys at random and shuffled them in a heap.  The trial consisted of two parts: joining the two tables, and doing lookups on the big table using the sample keys.  This simulated batch processing and on-line transaction processing.  The trial was done using a surrogate physical key of one column, then using a two-column composite, then a three-column composite, and so on up to 10 columns.  The same trial was repeated structuring the big table as a B-tree, a hash table, and an ISAM table. The cache was cleared between tests.  The benchmark was run on a <a href="http://community.actian.com/forum/blogs/rhann/129-benchmarking.html" target="_blank">terrible, ancient low-spec machine</a>.<br />
<br />
Pervasive folk-wisdom says the performance should get dramatically worse going from a one-column physical key to an N-column physical key.  Here is what happened:<img src="http://www.rationalcommerce.com/images/composite-keys.PNG" border="0" alt="" /><br />
Wow.<br />
<br />
Evidently the belief that composite keys perform poorly is just flat-out wrong!  Possibly it is true of other products but it certainly isn't true of Ingres.  (I am not certain it is true of other products either, but I don't care about other products.  I am an Ingres bigot to the bone.)<br />
<br />
How many columns is too many in a composite key?  Beats me.  My guess is way more than ten.  (I've never seen even a ten attribute logical key.  They must be quite rare.)  If a ten-column key makes sense to the business it makes sense to me—and if I don't understand it the burden is all on me to learn.<br />
<br />
So what can we conclude from this?  Well one thing we certainly can't conclude is that composite keys perform so badly they should be avoided just on principle.  <br />
<br />
<b>To introduce a spurious surrogate key merely on the <i>assumption </i>of a performance advantage is emphatically not &quot;best practice&quot; nor &quot;professional&quot;. </b> Quite the opposite.<br />
<br />
Now I don't want to leave you with the mistaken idea that surrogate keys are never beneficial.  In <a href="http://community.actian.com/forum/blogs/rhann/130-surrogate-keys-part-4-search-niche.html" target="_blank">Part 4</a> I'll look for cases where they do help.</div>

]]></content:encoded>
			<dc:creator>rhann</dc:creator>
			<dc:publisher>131</dc:publisher>
			<guid isPermaLink="true">http://community.actian.com/forum/blogs/rhann/128-surrogate-keys-part-3-surrogates-composites.html</guid>
		</item>
		<item>
			<title>Surrogate Keys: Part 2, The Boring Bit</title>
			<link>http://community.actian.com/forum/blogs/rhann/127-surrogate-keys-part-2-boring-bit.html</link>
			<pubDate>Tue, 02 Apr 2013 14:42:00 GMT</pubDate>
			<description><![CDATA[There's a lot of poorly-chosen terminology and badly explained theory behind keys so I want take a shot at clearing things up so that my next fews...]]></description>
			<content:encoded><![CDATA[<div>There's a lot of poorly-chosen terminology and badly explained theory behind keys so I want take a shot at clearing things up so that my next fews rants can be more ranty.  If you're really not keen on this you can skip straight to the <a href="http://community.actian.com/forum/blogs/rhann/128-surrogate-keys-part-3-surrogates-fail-impress.html" target="_blank">third posting</a> now, but the last posting isn't going to make much sense if you don't come back and read this first.  (I'll put a reminder in the last posting.)<br />
<br />
As well as being a bit of a conversational tinderbox the term &quot;key&quot; is grossly overloaded.  In these postings I will rant about both logical and physical keys:  <ul><li>a <i>logical key</i> is a column or an irreducible set of columns, the value of which is unique to a row in a table</li>
<li>  a <i>physical key</i> is a column or set of columns, the value of which can be used by the DBMS to rapidly locate the row container(s) in the underlying storage.</li>
</ul>To put it crudely: the value of a logical key is the &quot;name&quot; of a row, so you can <i>say </i>things about that specific row; the physical key is used to cluster records for rapid access. <br />
<br />
<font size="1"><blockquote><b><font color="Red">UPDATE</font></b>: Following an offline conversation I realize that it's not even clear what a row <i>is</i>.  A row is not a container—it is the content.   I've slightly amended the wording of the paragraph above with that in mind.  Perhaps it would be better if we spoke of &quot;facts&quot; and &quot;records&quot; instead of calling them both &quot;rows&quot;, but I don't think that would catch on.</blockquote></font><br />
<br />
A physical key need not consist wholly (nor even in part) of columns from a logical key.  On the other hand it is quite rare that the columns of a logical key aren't wholly or in part used in a physical key too.  <br />
<br />
Every table has to have a logical key and it may have many, and they may overlap.  The same table can also have zero or more physical keys.  (A heap has no physical key but it has to have a logical key.)<br />
<br />
A good key is usually said to be:<ul><li>unique</li>
<li>stable</li>
<li>simple</li>
<li>familiar</li>
</ul>The only objective criterion is uniqueness—that's what makes it a logical key.  The others are entirely subjective and follow from the fact that we will probably also want to use the columns of a logical key for a physical key.<br />
<br />
<i>Stable</i> does not mean immutable; it means &quot;changes only in exceptional circumstances&quot;.  Changing a couple or ten times over the lifetime of the row is definitely tolerable.  This is important because one of the arguments put forward for introducing a surrogate key is that it is not vulnerable to data-entry errors and therefore never needs to be corrected.  If you use a credit card number as a key and you have references to it in lots of other tables, and you need to correct it, you have to correct it everywhere it appears.  <br />
<br />
I say &quot;so what&quot;?  That's what ON UPDATE CASCADE is for.  <br />
<br />
<i>Simple</i> does not exclude composite keys; it excludes unwieldy keys.  I think we can agree that a ten-column composite key is well on the way to being a nuisance.  Similarly we can probably agree that two- or even three-column composites are pretty manageable.  Just where you draw the line is down to your personal psychology and I'm willing to be fairly flexible on where you draw it as long as it's more than three columns and less than too many.  <br />
<br />
I think we can also agree that using an excessively long string for a key can be  a problem. But how long is excessively long?  Again, I'm willing to be flexible but I'd want some demonstrable gain from ditching a familiar natural key, so it's going to be have to be very long before I'd agree there's much of a case for using a surrogate instead.<br />
<br />
Familiarity is hugely important for usability and it's tough to benchmark, but I say having to look up the surrogate first when you already know the natural value is a titanic pain in the you-know-what.  More so when you have to navigate via three or four tables each with a new surrogate only because some dogmatic clown had the idea it was &quot;professional&quot; to eliminate natural keys.<br />
<br />
That's enough theory for now.  Time to get rough.  In the <a href="http://community.actian.com/forum/blogs/rhann/128-surrogate-keys-part-3-surrogates-fail-impress.html" target="_blank">next section</a> I'll expose the claim that surrogate keys improve performance for the nonsense it is.<br />
<br />
<font size="1"><blockquote><b>Digression 1:</b> I think we DBAs tend to over-specify physical keys.  The physical key needs to be just good enough to find the right page, not the specific row.  A lot of unnecessary cost is incurred by creating over-specific physical keys.  (That's yet another rant for another day.)</blockquote></font><br />
<font size="1"><blockquote><b>Digression 2: </b>You will know the term &quot;primary key&quot;.  It is just a logical key.  The only thing remotely special about it is the table designer gave it a gold star and a box of chocolates (for some reason that I'm sure seemed to make sense at the time).   <br />
<br />
When one declares that a logical key is the PRIMARY KEY Ingres automatically also creates a physical key (secondary index) using the same column(s).  That's not a law of nature, it's just what Ingres does and it's not the intended reason for declaring a key primary.  I don't know what the intended reason is.  It's probably some kind of New Age desire to share one's feelings, no matter how flakey or ill-judged.<br />
<br />
I won't distract you by starting yet another rant just now, but if you detect a note of disdain when I write about primary keys you are not imagining it.  I won't mention the term again—everything I have to say about logical keys applies to so-called primary keys too.</blockquote></font></div>

]]></content:encoded>
			<dc:creator>rhann</dc:creator>
			<dc:publisher>131</dc:publisher>
			<guid isPermaLink="true">http://community.actian.com/forum/blogs/rhann/127-surrogate-keys-part-2-boring-bit.html</guid>
		</item>
		<item>
			<title>Benchmarking</title>
			<link>http://community.actian.com/forum/blogs/rhann/129-benchmarking.html</link>
			<pubDate>Tue, 02 Apr 2013 11:31:40 GMT</pubDate>
			<description>I am a big fan of benchmarking and load-testing.  Intuition and common-sense are truly terrible guides to what is efficient. I am frequently...</description>
			<content:encoded><![CDATA[<div>I am a big fan of benchmarking and load-testing.  Intuition and common-sense are truly terrible guides to what is efficient. I am frequently surprised at what I discover when I start looking under the rocks.<br />
<br />
Recently I've been involved in a discussion about the benefits of surrogate keys.  I've been doing some benchmarking to understand them better and I'll be posting some results soon.<br />
<br />
When I do this kind of benchmarking I like to create worst-case scenarios.  Knowing the worst possible outcome and designing for it, I can be pretty confident that when I deploy live, in production, the real performance can only be better.<br />
<br />
For the benchmarking I've just been doing I have used the worst machine I own.  It's a single-core, 1.3GHz workstation with 1Gb of RAM and a single low-spec hard drive.  The only good thing about it is that it's running CentOS Linux.<br />
<br />
To ensure the worst possible Ingres performance I have configured a modest DMF cache.  I clear the DMF cache between trials by setting <a href="http://www.kbcomputer.com/trace_pts.html" target="_blank">trace point DM421</a>.  <br />
<br />
The file system cache is highly effective so it also has to be cleared.  I was reminded of just how effective it is when I forgot to clear it.  The difference was night and day.   When I noticed the error I fixed the program to clear it by disconnecting all Ingres sessions from the test database (so the Ingres server process fully closes all its files) then executing <font face="Lucida Console"><b>sync; echo 3 &gt; /proc/sys/vm/drop_caches</b></font> as root.<br />
<br />
BTW, if anyone knows a way to clear the file system cache on a Windows machine I'd be very pleased to hear about it.<br />
<br />
When I generate test data I try to make it as challenging as possible.  For instance in my surrogate key benchmarks I did some tests involving very long strings of characters that varied only slightly, and only in the right-most positions—somewhat like what you would expect a list of fully qualified file pathnames to look like, only much, much worse.  <br />
<br />
When generating surrogate key values I used unordered sequences to minimize the benefits of clustering and cacheing.  And when I ran the tests, I made sure I shuffled all the key values to randomize access, maximizing disk head-motion and minimizing cache effectiveness.  <br />
<br />
I also used quite big tables, with millions of rows in hundreds of thousands of pages.<br />
<br />
I always do error-checking <i>and</i> row-count checking in my benchmarks.  Any time I get blindingly good performance I have to suspect I've broken a query so that it finds no rows.  <br />
<br />
Finally, any time I think I see an effect in a benchmark, I try to make it go away.  I try changing the order of trials in the benchmark.  I check whether defragmenting the disk has any impact.  I reboot and try again.  If possible I try a different version of Ingres too.  Finally, when I run out of ideas I show a friend and ask if they can replicate the effect.  It is very, very easy to fool oneself.  I distrust my results always. Nine times out of ten when I see an &quot;effect&quot; it turns out to be an error on my part.  <br />
<br />
The reward is that once in a while I discover something genuine and surprising and maybe counter-intuitive—like the new trick I found for improving the performance of queries on large hash tables....  But that is another story for another day.</div>

]]></content:encoded>
			<dc:creator>rhann</dc:creator>
			<dc:publisher>131</dc:publisher>
			<guid isPermaLink="true">http://community.actian.com/forum/blogs/rhann/129-benchmarking.html</guid>
		</item>
		<item>
			<title>Surrogate Keys: Part 1, Best Practice or Wrong-Headed Dogma?</title>
			<link>http://community.actian.com/forum/blogs/rhann/124-surrogate-keys-part-1-best-practice-wrong-headed-dogma.html</link>
			<pubDate>Mon, 01 Apr 2013 17:15:00 GMT</pubDate>
			<description><![CDATA[Recently I've been discussing surrogate keys over on comp.databases.theory...]]></description>
			<content:encoded><![CDATA[<div>Recently I've been discussing surrogate keys over on <a href="https://groups.google.com/forum/?fromgroups=#!topic/comp.databases.theory/mqZZw3ojnjA" target="_blank">comp.databases.theory</a>.<br />
<br />
Everyone seems to have passionate views on the virtues and desirability (or otherwise) of surrogate logical keys.  Me too, so this is going to be an unapologetic rant from start to finish.  <br />
<br />
Surrogate keys are used in lieu of natural keys.  Natural keys are identifying values that come from outside the application domain—they appear naturally in the data we receive.  If I send you my credit card number, that is a natural key that identifies me.<br />
<br />
For years people have been trying to tell me surrogate keys (or system-generated row IDs) are &quot;best practice&quot;.  This view has become so entrenched that people are lately trying to tell me that it is &quot;unprofessional&quot; to reject them. <br />
<br />
I dislike the damn things for very good reasons so I am stung by the implicit accusation that my designs are &quot;unprofessional&quot;.<br />
<br />
Mostly when people tell me such stuff it turns out to be second-hand dogma and they have no idea why they should believe it.  Other times they do manage an argument and it's usually either surrogate keys used as physical keys improve performance, or surrogate keys simplify programming.<br />
<br />
Actually there is a third argument that I am seeing increasingly often. I am told &quot;the ORM framework insists on surrogate keys&quot;.  Now even I know that's not true, but people say it.  I am not going to address that issue head-on.  It might be the subject of another rant some other time.  For now I'll just say that if someone wants to use Hibernate or similar, very good luck to them.  I wonder if their customer knows?<br />
<br />
As far as Ingres is concerned I make three counter-claims: <ol style="list-style-type: decimal"><li> <b>natural keys perform about as well as surrogates</b> (if not better)</li>
<li> <b>natural keys lead to far more usable database designs</b></li>
<li> <b>natural keys prevent serious logical design errors creeping in</b>.</li>
</ol>This series of five blog postings will explain all.  In the <a href="http://community.actian.com/forum/blogs/rhann/127-surrogate-keys-part-2-boring-bit.html" target="_blank">next posting</a> I'll cover some of the terminology and distinguish different kinds of keys.  You can skip straight to the <a href="http://community.actian.com/forum/blogs/rhann/128-surrogate-keys-part-3-surrogates-fail-impress.html" target="_blank">third posting</a> if you don't want the build-up.</div>

]]></content:encoded>
			<dc:creator>rhann</dc:creator>
			<dc:publisher>131</dc:publisher>
			<guid isPermaLink="true">http://community.actian.com/forum/blogs/rhann/124-surrogate-keys-part-1-best-practice-wrong-headed-dogma.html</guid>
		</item>
		<item>
			<title>Serialized Objects in the Database</title>
			<link>http://community.actian.com/forum/blogs/rhann/115-serialized-objects-database.html</link>
			<pubDate>Sat, 09 Mar 2013 17:31:46 GMT</pubDate>
			<description><![CDATA[I have recently been working with a colleague on an application to manage Java objects.  It's an interesting project because it highlights some...]]></description>
			<content:encoded><![CDATA[<div>I have recently been working with a colleague on an application to manage Java objects.  It's an interesting project because it highlights some things that are often hidden when we design databases and write applications.<br />
<br />
Long, long ago (1995) in a place far, far away (New Orleans) I attended a wonderful presentation by <a href="http://en.wikipedia.org/wiki/Christopher_J._Date" target="_blank">Chris Date</a> in which he pointed out a fundamental error then being made by the eager proponents of the new object databases that were starting to pop up.  Specifically, the OODB enthusiasts talked about classes as if they were analagous to table definitions—when in fact a class is a data type, if it's anything.¹ <br />
<br />
If classes are data types then SQL tables can perfectly well have columns with instances of a specified class as their values.  That is, if I have a class <i>Pizza</i> I can have a table with a column of Pizza instances and regardless of what objects might be nested inside a Pizza.<br />
<br />
In less than an hour one can create a Java program that instantiates and serializes objects and inserts rows containing the serialized objects into the database.  With a tiny amount more work the program can select and deserialize the objects.  It all works fine and none of it is done at the expense of relational theory (RT).<br />
<br />
RT explicitly ignores the internal structure of values—all values are <i>presumed </i>to be atomic and are treated as such.  (Obviously SQL provides functions to do things like extract substrings from supposedly &quot;atomic&quot; strings, but the essential operation of SQL doesn't depend on being able to do that.  Such functions are for convenience alone.)<br />
<br />
At first glance then, serializing objects looks like a slick answer to the often-heard grumble from OO programmers about having to laboriously unpack the content of their objects into rows in bazillions of tables when they want to &quot;persist&quot; them.  As long as the data management task doesn't depend on looking at the internals of the objects we can just serialize them and park them in the database till they're needed again, like putting a letter in an envelope and putting the envelope in the post.  The post office doesn't need to know anything about the content of the envelope to do its job perfect effectively—in fact we expect and insist that the post office will never know anything about the content of the letter.<br />
<br />
So is this a slick answer?  Well maybe, but most likely not.<br />
<br />
First off, doing this is sensible only if your <b>business problem</b> is the actual mangement of serialized objects.  Note I am talking about the business problem, <i>not</i> your solution to the business problem—there is a world of difference between those two and if it's not obvious stop and think about it till it is.<br />
<br />
Serialized objects <i>are</i> the values.  The contents (or the state) of those objects are <i>not</i> the values.  To the DBMS those values (the serialized objects) have no values within them; they are atomic.  Only the objects are accessible, like the envelopes to the post office.<br />
<br />
In almost thirty years I have encountered only one application that was fundamentally about transmitting and arbitrating access to objects.  <br />
<br />
Databases are for managing shared access to values in a way that ensures logical consistency.  To do that the DBMS has to be able to see the values.  Values concealed inside other values are invisible and inaccessible.  Values encoded inside objects belonging to a particular application or package, based on a particular language implementation, are accesssible only to that application or package.  In general, users of other tools or applications can never see the encoded values so shared access is severely limited.  The utility of the information is severely limited.  In fact it is limited to just the operations the programmers coded into the application.  <br />
<br />
It is extremely unlikely that a database would serve any other useful purpose when the data is encoded in that way.  <br />
<br />
Incidentally, I should point out that serialization is a considerable can of worms whether you're interested in databases or anything else.  It's a problem for the OO people to address.  If you know about the issues you might have thought of a way of dealing with them, and if you don't, well, you'll find out soon enough...<br />
<blockquote><font size="1">¹ Those of you who were at Chris Date's presentation will remember the impotent fury of the next speaker, who wanted to promote his hideous product which was entirely based on the error!  You couldn't have made it up. It was glorious.</font></blockquote></div>

]]></content:encoded>
			<dc:creator>rhann</dc:creator>
			<dc:publisher>131</dc:publisher>
			<guid isPermaLink="true">http://community.actian.com/forum/blogs/rhann/115-serialized-objects-database.html</guid>
		</item>
		<item>
			<title>Customizing Keyboard Mapping in OpenROAD</title>
			<link>http://community.actian.com/forum/blogs/howle01/122-customizing-keyboard-mapping-openroad.html</link>
			<pubDate>Fri, 04 Jan 2013 15:40:46 GMT</pubDate>
			<description>Every key on your keyboard is identified by a virtual key code. Virtual keys provide a mechanism to represent any key or key combination that could...</description>
			<content:encoded><![CDATA[<div>Every key on your keyboard is identified by a virtual key code. Virtual keys provide a mechanism to represent any key or key combination that could be issued from the keyboard. Virtual keys—also called logical keys—mapped to physical keyboard keys. This article reveals how you can customize keyboard mappings.<br />
<br />
<b><font size="+1">The Default Keyboard Map File</font></b><br />
<br />
When OpenROAD starts, it performs a default mapping of logical key names to physical keyboard keys. The file %II_SYSTEM%\ingres\files\default.kbd reflects the internal default keyboard mapping (if the file is unchanged since OpenROAD installation). All entries in the default keyboard map are tabulated in <a href="http://docs.actian.com/openroad/6.0/workbench-user-guide/4506-keyboard-file-map-example" target="_blank">Keyboard Map File Example</a>.<br />
<br />
You can customize or override the default keyboard map file to map an alternative scheme of logical names to physical keyboard keys that may be more appropriate for your needs than the default mapping.<br />
<br />
<b><font size="+1">Specifying a Different Keyboard Map File</font></b><br />
<br />
To change keyboard mapping, we recommend that you follow these basic steps:<ol style="list-style-type: decimal"><li>Copy the default.kbd file and rename it.</li>
<li>Point OpenROAD to the new file through one of the following environment variables.</li>
<li>Modify the copy.</li>
</ol><b>Copy the Default.kbd File</b><br />
<br />
Copy the default.kbd file in %II_SYSTEM%\ingres\files\. You can store the copy in the same directory or move it elsewhere. You may name it whatever you want, but where you store the file and what you name it determines which OpenROAD environment variable you must set.<br />
<br />
<b>Specify an Environment Variable to Point OpenROAD to the New Mapping File</b><br />
<br />
There are two environment variables you can use to specify a different keyboard map file. When OpenROAD is first installed, neither of the variables is set. (OpenROAD uses its own internal version, represented in the installed default.kbd, until one of these variables is defined.)<br />
<br />
<b>II_KEYBOARD</b><blockquote>Specifies the prefix name of a text file containing the custom keyboard mapping. OpenROAD makes two assumptions about the file specified with II_KEYBOARD:<ul><li>The file has an extension of &quot;.kbd&quot; (for example, custom.kbd).</li>
<li>The file resides in the &quot;files&quot; directory of the OpenROAD installation: %II_SYSTEM%\ingres\files\<i>prefix_name</i>.kbd</li>
</ul></blockquote><b>II_KEYBOARD_FILE</b><blockquote>Specifies the full path, file name, and extension of a keyboard mapping file that either does not have the .kbd suffix or does not reside in the &quot;files&quot; directory of your OpenROAD installation, for example: C:\MyDirectory\custom.keyboard. Specifying this variable overrides the II_KEYBOARD variable.</blockquote>The file you specify will be used the next time you start OpenROAD. But you must first modify the mappings in the file.<br />
<br />
For more information about how to set environment variables in OpenROAD, see <a href="http://docs.actian.com/openroad/6.0/workbench-user-guide/4486-environment-variables" target="_blank">Environment Variables</a>.<br />
<br />
<b>Edit Your Custom Keyboard Map File</b><br />
<br />
After copying the default.kbd file to a custom file and pointing OpenROAD to it, you must customize the mappings in the file.<br />
<br />
The OpenROAD keyboard map file is a text file with a specific format. The file describes 24 OpenROAD system-defined keys and 36 user-defined keys. The file contains one line for each key with four entries on each line. The entries are arranged in columns separated by tabs. All four columns are mandatory. For example:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="alt2" dir="ltr" style="
		margin: 0px;
		padding: 6px;
		border: 1px inset;
		width: 640px;
		height: 50px;
		text-align: left;
		overflow: auto">-24    &quot;&quot;              VK_PAUSE           SK_BREAK
-23    Shift+Ctrl+S    Shift-Ctrl-VK_S    SK_SAVE_AS</pre>
</div>Because the contents of some columns require specific values, it's best to copy an existing keyboard map file as a template if you want to customize the mapping. See the previous section.<br />
<br />
The following table describes the columns, left to right:<br />
<br />
<b>Column 1</b><blockquote>Index that OpenROAD uses to map the key. It is read into memory and always must match the text label in column 4. Do not change the entries in this column.</blockquote><b>Column 2</b><blockquote>Text that appears in the pull-down menu for the speed key.</blockquote><b>Column 3</b><blockquote>Virtual key name for the keystroke that occurs (see <a href="http://docs.actian.com/openroad/6.0/workbench-user-guide/4505-keyboard-mapping" target="_blank">Keyboard Mapping</a>).</blockquote><b>Column 4</b><blockquote>Internal symbol name used by OpenROAD, which must match the text label in column 1 (see <a href="http://docs.actian.com/openroad/6.0/language-reference-guide/2762-speedkey-settings" target="_blank">SpeedKey Settings</a>). Do not change the entries in this column.</blockquote>For example:<br />
<br />
Index: -23<br />
Pull-down Menu Text: Shift+Ctrl+S<br />
Virtual Key Name: Shift-Ctrl-VK_S<br />
Internal Symbol Name:  SK_SAVE_AS<br />
<br />
Index: -22<br />
Pull-down Menu Text: Shift+Ctrl+R<br />
Virtual Key Name: Shift-Ctrl-VK_R<br />
Internal Symbol Name:  SK_REPLACE_FIND<br />
<br />
All 104 virtual key definitions are listed in <a href="http://docs.actian.com/openroad/6.0/workbench-user-guide/4505-keyboard-mapping" target="_blank">Keyboard Mapping</a>. <br />
<br />
The changes you make to your keyboard mapping file will be used the next time you start OpenROAD.<br />
For a discussion of how to assign speed keys in OpenROAD, see <a href="http://community.actian.com/forum/blogs/howle01/121-defining-speed-keys.html" target="_blank">Defining Speed Keys</a>.</div>

]]></content:encoded>
			<dc:creator>howle01</dc:creator>
			<dc:publisher>1874</dc:publisher>
			<guid isPermaLink="true">http://community.actian.com/forum/blogs/howle01/122-customizing-keyboard-mapping-openroad.html</guid>
		</item>
		<item>
			<title>Defining Speed Keys</title>
			<link>http://community.actian.com/forum/blogs/howle01/121-defining-speed-keys.html</link>
			<pubDate>Wed, 02 Jan 2013 16:11:37 GMT</pubDate>
			<description>A speed key is a keyboard shortcut that invokes a menu option or toggle state typically invoked by mouse clicking. Assigning a speed key to a menu...</description>
			<content:encoded><![CDATA[<div>A speed key is a keyboard shortcut that invokes a menu option or toggle state typically invoked by mouse clicking. Assigning a speed key to a menu button or menu toggle lets the user press Alt plus a speed key rather than selecting the menu item. For a menu button, pressing the speed key combination executes the command. For a menu toggle, pressing the speed key combination switches the option between the on and off states.<br />
<br />
OpenROAD lets you assign speed keys to menu buttons and toggles in your applications by selecting a logical key name for the menu item from a list of supplied constants. The logical key assigned to the menu item may map to the keys on physical keyboards differently. <br />
<br />
<b><font size="+1">Keyboard Map Files</font></b><br />
<br />
If a key is defined in the mapping file, it will activate if assigned to an actual menu item. For example, if the VK_RETURN key is mapped to SK_USER1 and SK_USER1 is not used, it does not change any behavior. On the other hand, if it is assigned to a menu item attached to the frame, it overrides the default behavior and raises that event block.<br />
<br />
The same mapping is used for all platforms. The file %II_SYSTEM%\ingres\files\default.kbd reflects the internal default keyboard mapping (if the file is unchanged since OpenROAD installation). All entries in the default keyboard map are tabulated in <a href="http://docs.actian.com/openroad/6.0/workbench-user-guide/4506-keyboard-file-map-example" target="_blank">Keyboard Map File Example</a>.<br />
<br />
There are 104 different key definitions available. OpenROAD has a limit of 59 slots available for speed key definitions that are active for the life of a session.<br />
<br />
<b><font size="+1">How You Can Assign Speed Keys</font></b><br />
<br />
In the Workbench Menu Editor, you can associate a predefined speed key with a menu item (button or toggle) by using the Property Inspector to set the SpeedKey property. (System constant settings are listed in <a href="http://docs.actian.com/openroad/6.0/language-reference-guide/2762-speedkey-settings" target="_blank">SpeedKey Settings</a>.) The physical key mappings for these logical keys can be different for each system. To assign your own logical key, select one of the SK_USER# options, where # is 1–36.<br />
<br />
<b><font size="+1">How You Can Define an Alt Speed Key</font></b><br />
<br />
OpenROAD can set Alt speed keys for Button, Toggle, and Radio fields.<br />
<br />
To position an underscore character, indicating which Alt speed key is desired, place an ampersand (&amp;) prior to the character to be underscored when you create the label for the field, for example, &quot;&amp;Save&quot; to underscore the S. You can create the label in the Frame Editor's Property Inspector for the field, or it may be created or changed dynamically by your 4GL code.<br />
<br />
OpenROAD maintains the dynamic speed key table and associates the speed key with the field. This is done automatically for three types of fields: buttons, toggles, and radio fields.<br />
<br />
<b><font size="+1">Considerations When Defining Alt Speed Keys</font></b><br />
<br />
When defining Alt speed keys, consider the following issues:<br />
<br />
<b>Control Bias</b><blockquote>Alt speed keys are activated only if the bias of the field with which they are associated is <a href="http://docs.actian.com/openroad/6.0/language-reference-guide/2733-field-bias-settings" target="_blank">FB_CHANGEABLE or FB_LANDABLE</a>. When the Alt key and the underscored character are pressed, it is as if the mouse button is clicked while the cursor is positioned over the field.</blockquote><b>Printable Characters</b><blockquote>The characters that can be used for Alt speed keys are all the printable characters in the current character set, except space (&quot; &quot;) and ampersand (&quot;&amp;&quot;). Characters whose internal value is greater than 127 (0x7F) are supported so long as they can be typed without using the Alt key and the numeric keypad. Alt+function keys are not supported (except in the user-defined <a href="http://docs.actian.com/openroad/6.0/workbench-user-guide/3816-speed-key-mapping" target="_blank">speed key tables</a>.</blockquote><b>Case Significance</b><blockquote>The case of letters used as Alt speed keys is not significant. For example, both of the following button labels have Alt+K as the speed key: &quot;O&amp;K&quot; and &quot;O&amp;k.&quot; (Therefore, Alt+K and Alt+Shift+K perform the same function.)</blockquote><b>Including the &quot;&amp;&quot; Character in a Label</b><blockquote>Use double ampersands (&quot;&amp;&amp;&quot;) in the label of a field if you want to display a single ampersand as part of the label. For example, &quot;This &amp;&amp; That&quot; displays as &quot;This &amp; That&quot; with no underscore (and no Alt speed key).</blockquote><b>Button Speed Keys</b><blockquote>If the label for a button contains an ampersand (&quot;&amp;&quot;), when the Alt key and the underscored character are pressed, the button is pressed as if the primary mouse button were clicked while the cursor is over the button. Focus behaviors, events, and so on, are the same as if the mouse were used.</blockquote><b>Toggle Speed Keys</b><blockquote>Both the ON-Label and the OFF-Label can have Alt speed keys. They can be the same (for example, &quot;&amp;On&quot; and &quot;&amp;Off&quot;) or different (such as &quot;O&amp;n&quot; and &quot;O&amp;ff&quot;).<br />
<br />
If they are different, only the one currently displayed is active. In the same manner as for buttons, using the Alt speed key is identical to clicking with the primary mouse button.</blockquote><b>Radio Button Speed Keys</b><blockquote>Any, all, or none of the buttons in a radio field can have Alt speed keys associated with them. Pressing the Alt speed key associated with a radio button selects that button. In the same manner as for button fields, using the Alt speed key is identical to clicking with the primary mouse button.</blockquote><b>Order of Precedence for Speed Keys</b><blockquote>Speed keys using the Alt key can be defined in the following ways:<br />
<br />
<b>Alt speed keys</b><blockquote>Defined by placing an ampersand in the label of a button, toggle, or radio button</blockquote><b>User speed keys</b><blockquote>Defined by creating a user-defined speed key file</blockquote><b>Menu speed keys</b><blockquote>Defined by creating a menu item with an ampersand in its label</blockquote>Only one action is performed when a speed key using the Alt key is pressed, even if that speed key is defined in more than one of the previous ways at the same time. The order of precedence for speed keys is Alt, User, then Menu.</blockquote><b>Limitations</b><blockquote>The following limitations apply to speed keys:<ul><li>Only one Alt speed key is supported per label.<br />
<br />
If more than one ampersand is included in the text for a label, only the character following the last ampersand will be the Alt speed key. Prior ones are ignored. This does not apply to double ampersands used as an escape to display a single ampersand.<br />
<br /></li>
<li>Duplicate Alt speed keys are not supported.<br />
<br />
Using the ampersand to define more than one field to have the same Alt speed key is not supported. If you use the ampersand in this way, only one of the fields will actually be associated with that Alt speed key. The field chosen cannot be predicted and is subject to random fluctuations while the frame is running. (Toggle fields may use the same Alt speed key for their ON-Label and OFF-Label, since only one of these will be active at a given time.) Take care when assigning Alt speed keys dynamically.</li>
</ul></blockquote><b><font size="+1">MenuButton.SpeedKey Attribute</font></b><br />
<br />
Data Type: integer<br />
4GL Access: RW<br />
<br />
The SpeedKey attribute provides a numbered speed key that the end user can press to select the MenuButton.<br />
<br />
Pressing the speed key triggers any click events specified for the MenuButton.<br />
<br />
You can set user-defined speed keys 1–36 by using those integer values directly. OpenROAD also provides a special set of constants for the standard speed keys used in an application (for example, SK_SAVE and SK_UNDO). The keys associated with these constants vary for each system.<br />
<br />
Descriptions of system constant values and their numeric equivalents are listed in <a href="http://docs.actian.com/openroad/6.0/language-reference-guide/2762-speedkey-settings" target="_blank">SpeedKey Settings</a>. For the physical key mappings for these constants, see the appendix <a href="http://docs.actian.com/openroad/6.0/workbench-user-guide/3816-speed-key-mapping" target="_blank">Speed Key Mapping</a> in the <i>Workbench User Guide</i>.<br />
<br />
<b><font size="+1">How to Construct a File Menu Group That Contains Speed Keys</font></b><br />
<br />
The following discussion steps through the construction of the File menu group.<ol style="list-style-type: decimal"><li>Create the MenuGroup object:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="alt2" dir="ltr" style="
		margin: 0px;
		padding: 6px;
		border: 1px inset;
		width: 640px;
		height: 34px;
		text-align: left;
		overflow: auto">top_menu = MenuGroup.Create(); /* File Menu */</pre>
</div></li>
<li>Define the TextLabel and internal name for the File menu group:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="alt2" dir="ltr" style="
		margin: 0px;
		padding: 6px;
		border: 1px inset;
		width: 640px;
		height: 50px;
		text-align: left;
		overflow: auto">top_menu.TextLabel = 'File';
top_menu.Name = 'file_menu';</pre>
</div>The text assigned to the TextLabel attribute is displayed by the frame in its menu bar. The preceding code, therefore, causes the word &quot;File&quot; to appear as one of the selections available in the frame's initial menu. The value assigned to the Name attribute is the name of the reference variable pointing to that MenuGroup object.<br />
<br /></li>
<li>Define the two submenu options that appear when the user selects the File option from the menu bar: &quot;Commit and Close&quot; and &quot;Rollback and Close.&quot; Defining these operations follows the same procedures as creating the MenuGroup:<ul><li>Create the object for each item (in this case a MenuButton object).</li>
<li>Define the TextLabel and Name for each menu item.</li>
</ul><br />
The following code creates the first submenu item:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="alt2" dir="ltr" style="
		margin: 0px;
		padding: 6px;
		border: 1px inset;
		width: 640px;
		height: 66px;
		text-align: left;
		overflow: auto">test_menu = MenuButton.Create();
test_menu.Name = 'commit_menu';
test_menu.TextLabel = 'Commit and Close';</pre>
</div></li>
<li>In addition to letting the user commit the transaction and close the frame by selecting the Commit menu button, the dynamic frame provides a second way to commit and close. The example frame provides alternative access to the Commit operation by defining a speed key, which lets the user select the Close operation from the keyboard rather than using the mouse.<br />
<br />
The following code defines the speed key:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="alt2" dir="ltr" style="
		margin: 0px;
		padding: 6px;
		border: 1px inset;
		width: 640px;
		height: 34px;
		text-align: left;
		overflow: auto">test_menu.SpeedKey = SK_CLOSE;</pre>
</div></li>
<li>After each submenu option is defined, the following code attaches it to the field MenuGroup object:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="alt2" dir="ltr" style="
		margin: 0px;
		padding: 6px;
		border: 1px inset;
		width: 640px;
		height: 34px;
		text-align: left;
		overflow: auto">test_menu.ParentMenuGroup = top_menu;</pre>
</div>The preceding statement makes the MenuGroup object represented by top_menu to be the parent of the MenuButton object represented by test_menu.<br />
<br /></li>
<li>After defining all of the individual items for the MenuGroup, the following code attaches the MenuGroup itself to the MenuBar object:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="alt2" dir="ltr" style="
		margin: 0px;
		padding: 6px;
		border: 1px inset;
		width: 640px;
		height: 34px;
		text-align: left;
		overflow: auto">top_menu.ParenTMenuGroup = test_frame.StartMenu;</pre>
</div>The following is the complete code that constructs both menu groups that belong to the menu bar:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="alt2" dir="ltr" style="
		margin: 0px;
		padding: 6px;
		border: 1px inset;
		width: 640px;
		height: 498px;
		text-align: left;
		overflow: auto">top_menu = MenuGroup.Create();   /* File Menu */
top_menu.TextLabel = 'File';
top_menu.Name = 'file_menu';

test_menu = MenuButton.Create();   
    /* Commit and close menu item */
test_menu.Name = 'commit_menu';
test_menu.TextLabel = 'Commit and Close';
test_menu.SpeedKey = SK_CLOSE;
test_menu.ParentMenuGroup = top_menu; 
    /* Attach to File menu */

test_menu = MenuButton.Create();  
    /* Rollback and close menu item */
test_menu.Name = 'rollback_menu';
test_menu.TextLabel = 'Rollback and Close';
test_menu.ParentMenuGroup = top_menu;  
    /* Attach to File menu */
top_menu.ParentMenuGroup = test_frame.StartMenu;
/* Now, create the Edit menu */
top_menu = MenuGroup.Create();   /* Edit Menu */
top_menu.TextLabel = 'Edit';
top_menu.Name = 'edit_menu';

test_menu = MenuButton.Create();      
    /* Delete menu item */
test_menu.Name = 'delete_menu';
test_menu.TextLabel = 'Delete and Next';
test_menu.SpeedKey = SK_DELETE;
test_menu.ParentMenuGroup = top_menu; 
    /* Attach to Edit menu */

test_menu = MenuButton.Create();     
    /* Update menu item */
test_menu.Name = 'update_menu';
test_menu.TextLabel = 'Update and Next';
test_menu.ParentMenuGroup = top_menu;   
    /* Attach to Edit menu */

test_menu = MenuButton.Create(); 
    /* Next menu item */
test_menu.Name = 'next_menu';
test_menu.SpeedKey = SK_NEXT;
test_menu.TextLabel = 'Next';
test_menu.ParentMenuGroup = top_menu;     
    /* Attach to Edit menu */

/* Attach to Frame */
top_menu.ParentMenuGroup = test_frame.StartMenu;</pre>
</div></li>
</ol>For more information about the various types of menu objects, see the <i><a href="http://docs.actian.com/openroad/6.0/language-reference-guide" target="_blank">Language Reference Guide</a></i>.<br />
<br />
For more information on keyboard mapping, see <a href="http://community.actian.com/forum/blogs/howle01/122-customizing-keyboard-mapping-openroad.html" target="_blank">Customizing Keyboard Mapping</a>.</div>

]]></content:encoded>
			<dc:creator>howle01</dc:creator>
			<dc:publisher>1874</dc:publisher>
			<guid isPermaLink="true">http://community.actian.com/forum/blogs/howle01/121-defining-speed-keys.html</guid>
		</item>
		<item>
			<title>Understanding Database Connection Profiles in OpenROAD 6.0</title>
			<link>http://community.actian.com/forum/blogs/howle01/120-understanding-database-connection-profiles-openroad-6-0.html</link>
			<pubDate>Fri, 30 Nov 2012 21:13:48 GMT</pubDate>
			<description>A database connection profile is a collection of settings that Workbench uses to establish a connection with a local or remote database. To use any...</description>
			<content:encoded><![CDATA[<div>A database connection profile is a collection of settings that Workbench uses to establish a connection with a local or remote database. To use any of the Workbench tabs other than the Connect tab, you first must connect to a database through a database connection profile. This means you must create at least one connection profile before you can connect to a database to do application development using Workbench.<br />
<br />
<div align="center"><img src="http://community.actian.com/forum/blogs/howle01/attachments/14d1354305905-understanding-database-connection-profiles-openroad-6-0-edit_connection_profile.jpg" border="0" alt="" /></div><br />
Connection parameters include:<ul><li>Profile name</li>
<li>Description of the profile</li>
<li>Database management system (Ingres, Oracle, Microsoft SQL Server, or IBM DB2 UDB)</li>
<li>Connection type (local, vnode, or dynamic)</li>
<li>Database name</li>
<li>Connect as username</li>
<li>Group identifier for the session</li>
<li>Role identifier for the application image</li>
<li>Optional flags to use on the connect statement</li>
<li>Profile icon</li>
</ul>The Connection Profile portlet provides other connection parameters, depending on the value you choose for the Type parameter.  The above example shows the connections parameters available if Type is set to Local. If Type is set to Vnode, you must define the additional Node parameter with the remote virtual node name. If you set Type to Dynamic, you must define additional parameters for the dynamic connection definition (server, installation, and protocol).<br />
<br />
For more information about fields and parameters used in the OpenROAD Startup Assistant, see <a href="http://docs.actian.com/openroad/6.0/workbench-user-guide/1205-openroad-startup-assistant-and-connection-details-properties" target="_blank">OpenROAD Startup Assistant and Connection Details Properties</a>.<br />
<br />
<b><font size="+1">Ways to Define a Database Connection Profile</font></b><br />
<br />
The first time you start OpenROAD 6.0, the OpenROAD Startup Assistant prompts you to create a new database connection profile. Subsequently, you can create profiles to connect to existing databases or, if OpenROAD is installed in an Ingres installation, you can create a new database along with the connection.<br />
<br />
You create database connection profiles from the Connect tab using the Connection Profile Assistant, a handy wizard that guides you through the creation process. To start the wizard, click File, New, Profile.<br />
<br />
<div align="center"><img src="http://community.actian.com/forum/blogs/howle01/attachments/13d1354308004-understanding-database-connection-profiles-openroad-6-0-connection_profile_assistant.jpg" border="0" alt="" /></div><br />
<b><font size="+1">New Location for Database Connection Profiles in OpenROAD 6.0</font></b><br />
<br />
When you upgrade from OpenROAD 5.1 to OpenROAD 6.0 on newer 64-bit Windows platforms, the path to where database connection profiles are stored changes. To continue using profiles you created in OpenROAD 5.1, you must copy the 5.1 profile files to the OpenROAD 6.0 directory or recreate the profiles in Workbench. Here's how.<br />
<br />
<b>Finding the Location of Your OpenROAD Profiles</b><br />
<br />
You can find the location of your profiles by issuing the following command at the OpenROAD command prompt:<br />
<blockquote><font face="courier">openroad /profiles</font></blockquote>The output will look something like the following, depending on your version of Windows:<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="alt2" dir="ltr" style="
		margin: 0px;
		padding: 6px;
		border: 1px inset;
		width: 640px;
		height: 210px;
		text-align: left;
		overflow: auto">=========================================================
openroad: The following options were selected by openroad
---------------------------------------------------------
  OPTION_DBNAME                 = qtdemodb
  OPTION_PROFILES               = TRUE
---------------------------------------------------------
OR_CONFIG  = &quot;C:\Documents and Settings\All Users\Application Data\OpenROAD\Profiles\&quot;
    Profile  = &quot;%OR_CONFIG%\user01.prc&quot;
    Profile  = &quot;%OR_CONFIG%\user01.prf&quot;
    Profile  = &quot;%OR_CONFIG%\user01.qp&quot;
    Profile  = &quot;%OR_CONFIG%\user01.tld&quot;
    Profile  = &quot;%OR_CONFIG%\user01kbd.prc&quot;</pre>
</div>OR_CONFIG is an environment variable that specifies the location of the OpenROAD profiles. This is set to a location that the user has write access. For more information about OR_CONFIG, see <a href="http://docs.actian.com/openroad/6.0/workbench-user-guide/4489-environment-variables-for-all-platforms" target="_blank">Environment Variables for All Platforms</a> and <a href="http://docs.actian.com/openroad/6.0/installation-and-configuration-guide/1313-openroad-command-check-openroad-status" target="_blank">openroad command—Check OpenROAD Status</a>.<br />
<br />
<b>Copying Profiles to Connect to the Same Ingres Instance</b><br />
<br />
If you're accessing the same Ingres instance in OpenROAD 6.0 that you used with OpenROAD 5.1, you can copy the database connection profiles from the OpenROAD 5.1 storage location to the new OpenROAD 6.0 location. Be sure to close OpenROAD before copying the files.<br />
<br />
<u>Windows Server 2008, Windows Vista, Windows 7</u><br />
<br />
Copy files from 5.1 location:<br />
<blockquote><font face="courier">%ALLUSERSPROFILE%\OpenROAD\Profiles</font></blockquote>Paste files to 6.0 location:<br />
<blockquote><font face="courier">%USERPROFILE%\AppData\Local\OpenROAD\Profiles\inst  allation_ID </font></blockquote><u>Windows Server 2003, Windows XP</u><br />
<br />
Copy files from 5.1 location:<br />
<blockquote><font face="courier">%ALLUSERSPROFILE%\Application Data\OpenROAD\Profiles</font></blockquote>Paste files to 6.0 location:<br />
<blockquote><font face="courier">%USERPROFILE%\Local Settings\Application Data\OpenROAD\Profiles\installation_ID</font></blockquote><b>Recreating Profiles to Connect to a New Ingres Instance</b><br />
<br />
If you want to connect to a new Ingres instance, at the end of installation or the first time you start Workbench, the OpenROAD 6.0 Startup Assistant will guide you through the process of creating a default database connection profile.<br />
<br />
For more information about creating new database connection profiles, see <a href="http://docs.actian.com/openroad/6.0/workbench-user-guide/1203-define-a-database-connection-profile" target="_blank">Define a Database Connection Profile</a>.<br />
<br />
<b><font size="+1">Starting Workbench from the Command Line to Connect with a Specific Connection Profile</font></b><br />
<br />
You can start Workbench 6.0 with a command line flag to specify a connection profile and optionally skip the splash screen:<br />
<blockquote><font face="courier">w4gldev runimage workbnch.img -/appflags profile=<i>profilename</i> nosplash</font></blockquote>When you start Workbench from the command line, <i>profilename</i> cannot contain embedded white space.<br />
<br />
<b><font size="+1">What You Can Do from the Workbench Connect Tab</font></b><br />
<br />
On the Connect tab, you can perform the following tasks concerning connection profiles:<ul><li>Define new connection profiles (see <a href="http://docs.actian.com/openroad/6.0/workbench-user-guide/1203-define-a-database-connection-profile" target="_blank">Define a Database Connection Profile</a>)</li>
<li>Modify existing connection profiles (see <a href="http://docs.actian.com/openroad/6.0/workbench-user-guide/1209-modify-a-database-connection-profile" target="_blank">Modify a Database Connection Profile</a>)</li>
<li>Delete connection profiles (see <a href="http://docs.actian.com/openroad/6.0/workbench-user-guide/1211-delete-a-database-connection-profile" target="_blank">Delete a Database Connection Profile</a>)</li>
<li>Set a connection profile as the default (see <a href="http://docs.actian.com/openroad/6.0/workbench-user-guide/6734-set-a-default-database-connection-profile" target="_blank">Set a Default Database Connection Profile</a>)</li>
</ul>In OpenROAD Workbench 6.0, when you double-click an existing connection profile in the Default Profile, Recent Profiles, or Connection Profiles portlet of the Connect tab, the connection is established and the Develop tab automatically opens using that connection. There, you can begin application development using the data in the connected database.<br />
<br />
For more information, see <a href="http://docs.actian.com/openroad/6.0/getting-started/1285-connect-to-a-database-through-a-connection-profile" target="_blank">Connect to a Database Through a Connection Profile</a>.</div>


<!-- attachments -->
	<div style="margin-top:10px">

		
		
		
			<fieldset class="fieldset">
				<legend>Attached Images</legend>
				<table cellpadding="0" cellspacing="3" border="0">
				<tr>
	<td><img class="inlineimg" src="http://community.actian.com/forum/ingres4/attach/jpg.gif" alt="File Type: jpg" width="16" height="16" border="0" style="vertical-align:baseline" /></td>
	<td><a href="http://community.actian.com/forum/blogs/howle01/attachments/13d1354305883-understanding-database-connection-profiles-openroad-6-0-connection_profile_assistant.jpg">Connection_Profile_Assistant.jpg</a> (18.5 KB, 114 views)</td>
</tr><tr>
	<td><img class="inlineimg" src="http://community.actian.com/forum/ingres4/attach/jpg.gif" alt="File Type: jpg" width="16" height="16" border="0" style="vertical-align:baseline" /></td>
	<td><a href="http://community.actian.com/forum/blogs/howle01/attachments/14d1354305905-understanding-database-connection-profiles-openroad-6-0-edit_connection_profile.jpg">Edit_Connection_Profile.jpg</a> (13.4 KB, 191 views)</td>
</tr>
				</table>
				</fieldset>
		
		

	</div>
<!-- / attachments -->
]]></content:encoded>
			<dc:creator>howle01</dc:creator>
			<dc:publisher>1874</dc:publisher>
			<guid isPermaLink="true">http://community.actian.com/forum/blogs/howle01/120-understanding-database-connection-profiles-openroad-6-0.html</guid>
		</item>
		<item>
			<title>Understanding the Port Keyword in the .NET Data Provider/JDBC Connection String</title>
			<link>http://community.actian.com/forum/blogs/teresa/119-understanding-port-keyword-net-data-provider-jdbc-connection-string.html</link>
			<pubDate>Fri, 30 Nov 2012 16:33:56 GMT</pubDate>
			<description>A C# application using the .NET Data Provider or a Java application using the JDBC Driver communicates to the Ingres or Vectorwise data sources...</description>
			<content:encoded><![CDATA[<div>A C# application using the .NET Data Provider or a Java application using the JDBC Driver communicates to the Ingres or Vectorwise data sources through the Data Access Server (DAS).  The application must specify in its connection string the hostname and the listen port for the DAS. The DAS listens on a network protocol port which is configured when the Ingres or Vectorwise instance is first installed. The port can be referenced by either its TCP/IP numeric port number or by an equivalent symbolic port identifier. By default the symbolic network protocol port identifier for the DAS is the two-letter instance ID followed by the number 7. For example, when installing Ingres or Vectorwise, if installing a default instance, the default symbolic port identifier for an Ingres instance is II7 and for a Vectorwise instance it is VW7. These equate to TCP/IP numeric ports 21071 and 27839 respectively. <br />
<br />
If you do not know the port value for your instance, you can search the errlog.log in the target instance for the strings, “DASVR” and “E_GC4803_NTWK_OPEN”.  This line will contain the following information, a reference to the  protocol TCP_IP and the port <i>xxx </i>information, where <i>xxx</i> is the symbolic port identifier followed by the numeric port number in parentheses.  It is important to ensure you are accessing the line that contains both strings, as other servers such as the communications server, COMSVR, will also open network ports. For more information about Data Access Server listen ports, see the section <a href="http://docs.actian.com/ingres/10s/connectivity-guide/1344-data-access-server-parametersconfigure-das" target="_blank">Data Access Server Parameters—Configure DAS</a>.<br />
<br />
More than one DAS can be configured on the DBMS server instance to provide a level of application load balancing. For example, within CBF you could set a startup count of 2 for the DAS and set the port parameter for the DAS to VW7+ which tells the system to start the first DAS on the symbolic port of VW7 and the second DAS on the symbolic port of VW8 . You could then configure your application connection string to allow application A to communicate to DAS VW7 and application B to communicate with DAS VW8, splitting up the application traffic between two different DASs.  You could also configure the application connection string to allow Application A to use either DAS since multiple ports can be specified.  Other more complex application load-balancing scenarios could also be configured.  Frequent readers of my blog may remember a recent article about <a href="http://community.actian.com/forum/blogs/teresa/116-scalable-load-balancing-oeon-dimea-net-connection-pooling.html" target="_blank">Scalable Load Balancing “On a Dime” with .NET Connection Pooling </a>that detailed a complex load balancing scenario. <br />
<br />
For more information on configuring and using multiple DAS, see the <a href="http://docs.actian.com/ingres/10s/connectivity-guide" target="_blank">Connectivity Guide</a>.</div>

]]></content:encoded>
			<dc:creator>teresa</dc:creator>
			<dc:publisher>26</dc:publisher>
			<guid isPermaLink="true">http://community.actian.com/forum/blogs/teresa/119-understanding-port-keyword-net-data-provider-jdbc-connection-string.html</guid>
		</item>
		<item>
			<title>Reading Ingres Database Configuration Files</title>
			<link>http://community.actian.com/forum/blogs/rhann/114-reading-ingres-database-configuration-files.html</link>
			<pubDate>Wed, 24 Oct 2012 08:51:29 GMT</pubDate>
			<description><![CDATA[In recent weeks I've been asked twice (kinda indirectly) about the Ingres database configuration file.   
 
Each Ingres database has a file in its...]]></description>
			<content:encoded><![CDATA[<div>In recent weeks I've been asked twice (kinda indirectly) about the Ingres database configuration file.  <br />
<br />
Each Ingres database has a file in its data area called <font face="Courier New">aaaaaaaa.cnf</font> which has information needed to open or recover the database.  There are several backup versions in other places too,  for instance there's a version in the dump area.<br />
<br />
It's a machine-readable binary file.   Normally the best tool to get most of the information from it is the <a href="http://docs.actian.com/ingres/10.0/command-reference-guide/1351-infodb-commanddisplay-database-information" target="_blank">infodb</a> utility, run from the command line or from <a href="http://esd.actian.com/product/Administration_Tools/Director_1.0" target="_blank">Actian Director</a>.<br />
<br />
If for some reason you want the information not shown in the infodb report, you need to dump the configuration file and intepret the fields yourself.  The structure of the file is not trivial and it has changed many times over the years, so the way you interpret it will depend on which Ingres version you are using.<br />
<br />
You could write your own configuration file dump utility using C or something, but probably the quickest way to do it is to use a hex editor such as <a href="http://hexedit.com/index.html" target="_blank">HexEdit</a>.  <br />
<br />
HexEdit treats all files as binary files. The most useful feature of HexEdit is the ability to define a template to show the location and extent of the fields in the file.  It also allows you to display field values in whatever way is convenient.  For example flag fields can be displayed in hex, count fields can be displayed as integers, and strings as...well, as strings.<br />
<br />
Crucially, templates can include some logic, so they can adapt to the actual content of the file.  This is important to us because the number and location of fields in an Ingres configuration file has changed from release to release, and we'd like to have one template that can figure out what it's looking at all by itself. <br />
<br />
I've created a HexEdit 4.0 <a href="http://www.rationalcommerce.com/uploads/cnf-template.zip" target="_blank">template file</a> that (I believe) will work for all configuration file formats from Ingres 10s back to Ingres 6.x.  I am confident it works for the current file format but I admit I've not gone to the trouble of resurrecting an old 6.x configuration file to test it.  Some minor fixes may be required.<br />
<br />
<b>Note</b> HexEdit will allow you to actually edit the configuration file.  <i>Editing the configuration file risks making your database inaccessible and possibly unrecoverable.</i>  I strongly advise you not to edit it.  (In any case, the most tempting changes—such as editing the location names—will probably not work.) <br />
<br />
If you want to write your own configuration file dumper or fix my template, you should refer to <br />
<a href="http://lxr.ingres.com/lxr/source//src/back/dmf/hdr/dm0c.h" target="_blank">src/back/dmf/hdr/dm0c.h</a> and <a href="http://lxr.ingres.com/lxr/source//src/back/dmf/dmp/dm0c.c" target="_blank">src/back/dmf/dmp/dm0c.c</a>.</div>

]]></content:encoded>
			<dc:creator>rhann</dc:creator>
			<dc:publisher>131</dc:publisher>
			<guid isPermaLink="true">http://community.actian.com/forum/blogs/rhann/114-reading-ingres-database-configuration-files.html</guid>
		</item>
		<item>
			<title>Accomplishments in OpenROAD Sprint at the 2012 German IUA (GIUA)</title>
			<link>http://community.actian.com/forum/blogs/teresa/118-accomplishments-openroad-sprint-2012-german-iua-giua.html</link>
			<pubDate>Tue, 23 Oct 2012 17:57:23 GMT</pubDate>
			<description><![CDATA[Members of the OpenROAD development team and customers participated in an OpenROAD Sprint October 9–11 in Langen, Germany.   It was Actian's first...]]></description>
			<content:encoded><![CDATA[<div>Members of the OpenROAD development team and customers participated in an OpenROAD Sprint October 9–11 in Langen, Germany.   It was Actian's first ever Sprint in Germany, and from all reports it was very successful. Here's what we accomplished.<br />
<br />
Joe Kronk, Teresa King, and Bodo Bergmann thoroughly reviewed the OpenROAD Enhancement queue prior to the event, looking for potential projects that could be completed in our time together. Participants also suggested projects that would be beneficial to them.  Although many projects were considered, the issues addressed were all OpenROAD enhancements that customers requested. Smaller enhancements will be considered for implementation at future Sprints so it is important that all of our customers log feature requests via the Support Mechanism. <br />
<br />
Continuing our recent trend, Bodo and Joe decided to focus on 4GL projects because 3GL projects are usually too large to tackle in the timeframe available, and the majority of attendees are 4GL developers.<br />
<br />
Considering that half the customers were participating in their first Sprint, they accomplished a significant amount of work.  <br />
<br />
<b>4GL Projects Tackled</b><br />
<br />
Stefan Massopust, Kim Ginnerup, Andreas Gießel, and Bodo completed the following 4GL enhancements:<br />
<ul><li><a href="http://community.actian.com/wiki/Ingres_OpenROAD_Projects/Frame_Editor_should_keep_selected_fields_on_Save" target="_blank">Keep fields selected in the Frame Editor after saving the frame.</a></li>
<li><a href="http://community.actian.com/wiki/Ingres_OpenROAD_Projects/Provide_Search_capabilities_in_Field_Tree_Window" target="_blank">Provide search capabilities in the Field Tree Window those in the Script Editor.</a></li>
<li>Enhance the Connection Profile Assistant:<ul><li><a href="http://community.actian.com/wiki/Ingres_OpenROAD_Projects/Connection_Wizard_Improvements" target="_blank">Provide consistent design and behavior throughout the wizard.</a></li>
<li><a href="http://community.actian.com/wiki/Ingres_OpenROAD_Projects/Correct_terms_for_installations_in_Connection_Profile_Assistant" target="_blank">Improve the DBMS Location page to make it easier to connect to local databases in installations other than the one OpenROAD is installed into. Use the terms &quot;Local Installation&quot; and &quot;Virtual Node&quot; instead of &quot;Local Machine&quot; and &quot;Remote Host&quot;.</a></li>
<li><a href="http://community.actian.com/wiki/Ingres_OpenROAD_Projects/Connection_Wizard_Improvements" target="_blank">Make the Edit button exit the Connection Profile Assistant as described on the Create Connection Profile panel. </a></li>
<li><a href="http://community.actian.com/wiki/Ingres_OpenROAD_Projects/Connection_Wizard_Improvements" target="_blank">On the Select the Database panel, if there is only one item available, select it; if there are more, select none of them. </a></li>
<li><a href="http://community.actian.com/wiki/Ingres_OpenROAD_Projects/Connection_Wizard_Improvements" target="_blank">Remember selections made on all panes when changing to next and previous panes.</a></li>
</ul></li>
<li><a href="http://community.actian.com/wiki/Ingres_OpenROAD_Projects/Toolbar_Editor_should_allow_to_insert_any_FormField" target="_blank">Allow any FormField to be inserted into an OpenROAD Toolbar. </a><ul><li>While testing this feature a 3GL bug was discovered when a tabfolder was inserted into the toolbar.  This bug was resolved at the Sprint by Joe and Thomas Christlieb to complete the implementation of the feature.</li>
</ul></li>
</ul><br />
<b>3GL Project Accomplished</b><br />
<br />
Although the plan was to focus on 4GL projects, Joe and Thomas completed one 3GL project previously logged as a customer enhancement request since it turned out to be a very simple change:<br />
<ul><li><a href="http://community.actian.com/wiki/Ingres_OpenROAD_Projects/Allow_FilePopup_dialogs_to_be_resizeable" target="_blank">Enable FilePopup dialogs to be resizable.</a></li>
</ul><br />
Participants considered other projects that at first glance appeared fairly easy to implement. However, it quickly became clear this wasn’t always the case because, if implemented incorrectly, there could be serious side effects on other parts of the system. Another specific request was researched but abandoned not because the idea wasn’t good, but because the proposed implementation would adversely impact the end user application.<br />
<br />
<b>Customer Challenges Resolved</b><br />
<br />
A Sprint is a good time to get the OpenROAD development team to look at your hard to reproduce problems.<br />
<br />
Thomas's customers had been seeing some abnormal terminations, but Thomas was having trouble providing reproducible test cases and sufficient data to expose the underlying problem.  Joe and Thomas spent some time analyzing traces and crash dumps and managed to get to the heart of one problem. Another one was resolved earlier this week.<br />
<br />
<b>More Than Just a Sprint</b><br />
<br />
Since all the slots at the German IUA were filled, Consolidate Systems took the opportunity to share some of the work that they are doing with OpenROAD. They delivered a presentation, &quot;<a href="http://community.actian.com/w/files/5/54/Langen_AUA_2012A.pdf" target="_blank">OpenROAD: A LEADER IN MOBILE REVOLUTION</a>,&quot; along with a live demo of two OpenROAD applications that run on the web and on mobile devices. It was very impressive.<br />
<br />
Because the attendees were unable to attend the German IUA and hear Emma McGrattan’s presentation about OpenROAD 6.2, Joe and Bodo delivered an informal presentation using content from the <a href="http://community.actian.com/wiki/Ingres_Roadmap/OpenROAD_6.2" target="_blank">OpenROAD 6.2 Roadmap </a>page to show the attendees where we are headed with the next major OpenROAD release. They demonstrated a chess application created to showcase some of the upcoming functionality.  General consensus was that we are headed in the right direction. <br />
<br />
<b>What Happens Next</b><br />
<br />
Bodo and Joe have returned from the Sprint and are already busy creating wiki pages on the <a href="http://community.actian.com/w/index.php/Ingres_OpenROAD_Projects#OpenROAD_Projects" target="_blank">OpenROAD project page</a> that describe the projects. This ensures that the code changes are submitted into our development codeline.  <br />
<br />
The features discussed in this article will be available in the OpenROAD 6.2 release. Projects for which a project page exists are linked to the <a href="http://community.actian.com/w/index.php/Ingres_OpenROAD_Projects#OpenROAD_Projects" target="_blank">project page</a>.  The completed Sprint projects also will be included in the upcoming 6.2 Workbench Express preview.<br />
<br />
<b>Summary</b><br />
<br />
Congratulations to all the participants for a job well done! The attendees were hopeful we would do another Sprint in Germany and, based on feedback, they're already looking forward to it.</div>

]]></content:encoded>
			<dc:creator>teresa</dc:creator>
			<dc:publisher>26</dc:publisher>
			<guid isPermaLink="true">http://community.actian.com/forum/blogs/teresa/118-accomplishments-openroad-sprint-2012-german-iua-giua.html</guid>
		</item>
	</channel>
</rss>
