milardj's Journal milardj's use Perl Journal en-us use Perl; is Copyright 1998-2006, Chris Nandor. Stories, comments, journals, and other submissions posted on use Perl; are Copyright their respective owners. 2012-01-25T02:32:45+00:00 pudge Technology hourly 1 1970-01-01T00:00+00:00 milardj's Journal Automated Build Process The company I work for now used to be a client of my previous employer. For whatever reason they decided to buy the source code and develop/support the product (a pharmacy claim adjudication system) on their own. The company is US based and they hired 11 of us (8 developers, 2 QA, and an architect) and set us up in an office in Canada. <p> The company is not a software development shop so the first year or so was<nobr> <wbr></nobr>... <i>interesting</i>. CM (configuration management) for our product (dozens of applications written in C, C++, PB, perl, sqlplus, Java comprised of 12K+ files) was left in the hands of our overloaded QA team. This responsibility gradually became my responsibility (I lead a team responsible for GUI, server infrastructure, financial subsystem, and database loads). </p><p> Here was our process at the start of the year: </p><ul> <li>developer checks out/modifies/checks in source</li> <li>developer fills out a paper 'code promotion form'</li> <li>CM collects the forms and starts the build process</li> <li>CM manually extracts the files from VM (Merant Version Manager) to Windows. Since VM is not task based and their labelling functionality is a joke (if you do a get based on label the app interogates *every* file in the repository to see if it has the specified label which can take up to 10 minutes per promotion form)</li> <li>CM manually ftps the extracted source to our build area on Unix</li> <li>CM determines if there are any database change dependencies if so migration scripts are manually applied to the dev database</li> <li>CM kicks off the build script</li> <li>CM ftp's the build to the QA staging area</li> <li>CM manually composes a build notification e-mail</li> <li>when QA is ready to apply the new build CM must apply any migration scripts to the QA database (and manually apply grants and create synonyms)</li> </ul><p> Depending on the stage of the release I was sometimes doing up to 5 builds a day at a loss of 2.5 to 5 hours of productivity a day. Keep in mind I was a hands on Team Lead - still developing for each release. </p><p> Our process now: </p><ul> <li>developer checks out/modifies/checks in source</li> <li>developer fills out a web 'code promotion form'</li> </ul><p> That's it. Happy times are here again. </p><p> The goal for 2006 is to introduce automated smoke and regression tests into the process (at least for core components like our OLTP engine) and generate pretty graphs like the Pugs team has done (<a href=""></a> - loads slowly).</p> milardj 2006-01-05T16:23:05+00:00 journal DOM/IE woes and mod_perl2 woes - Woe is me! I have a web page that allows for the definition and generation of reports. The report is defined by adding columns, selecting the value for that column, and allows shifting of columns. <p> The column definitions are wrapped in divs where each div has a id in the format column# </p><p> When shifting columns I move the actual div and (for whatever reason) change all the ids (the div and all childnodes) to reflect the new column number. </p><p> This works fine and the columns are shifted, when the form is submitted everything is fine *but* before the form is submitted things seem to be screwed up in IE. For example if I grab one of the elements within the div after shifting: </p><p> var name = document.getElementById("column1_name") alert( </p><p> The id displayed is the old id: column2_name!! </p><p> Please note that I *got* the element BY ID! </p><p> My mod_perl2 woes: I've installed the latest mod_perl2 (2.01) and libapreq2 (2.06-dev) and everything seems fine except for when I try to serve up excel files (generated by Spreadsheet::WriteExcel) </p><p> The sample mod_perl2 program for SS::WE sets headers/content type as: </p><p> <code> $r-&gt;headers_out-&gt;{'Content-Disposition'} = "attachment;filename=$filename"; $r-&gt;content_type('application/'); </code> </p><p> But I get an error when I run: </p><p>] Can't locate object method "STORE" via package "APR::Table" </p><p> The pod for APR::Table seems fine but the changelog for libapreq2 has the following: </p><p> <cite> Perl API [joes] Support for table set/add/delete methods is formally withdrawn. Technically this feature died with the module API refactoring in 2.05-dev. </cite> </p><p> Based on my error it would seem the "table" in question is probably APR::Table but why is the pod for APR::Table still showing set/store etc </p><p> I'm obviously missing something<nobr> <wbr></nobr>...</p> milardj 2005-08-17T14:49:56+00:00 journal I defy you* ... ... to read <a href="">this</a> (Perl6 is Here Today slide show) and not get excited. <p> * Perl developers who think P6 is fubar'd</p> milardj 2005-06-16T15:19:03+00:00 journal Vee belief in nossing, Lebowski! NOSSING!! <tt>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WAITRESS<br>&nbsp; &nbsp; &nbsp; &nbsp; You folks ready?<br><br>The German shouting stops.&nbsp; Dieter looks sourly up.<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DIETER<br>&nbsp; &nbsp; &nbsp; &nbsp; I haff lingenberry pancakes.<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; KIEFFER<br>&nbsp; &nbsp; &nbsp; &nbsp; Lingenberry pancakes.<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FRANZ<br>&nbsp; &nbsp; &nbsp; &nbsp; Sree picks in blanket.<br><br>The woman speaks to Dieter in German.&nbsp; He nods.<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DIETER<br>&nbsp; &nbsp; &nbsp; &nbsp; Lingenberry pancakes.</tt> milardj 2005-06-14T21:16:20+00:00 journal Well sir, it's this rug I have,really tied the room together <tt>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DUDE<br>&nbsp; &nbsp; They're nihilists.<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WALTER<br>&nbsp; &nbsp; Huh?<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DUDE<br>&nbsp; &nbsp; They kept saying they believe in<br>&nbsp; &nbsp; nothing.<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WALTER<br>&nbsp; &nbsp; Nihilists!&nbsp; Jesus.<br><br>Walter looks haunted.<br><br>&nbsp; &nbsp; Say what you like about the tenets of National Socialism,<br>&nbsp; &nbsp; Dude, at least it's an ethos.<br></tt> milardj 2005-06-14T21:10:36+00:00 journal A Very Good Thing It seems that Leo and Chip are tending to agree much more then disagree (opcodes, continuations/registers, fallback behaviour etc). This is a very good thing. <p> Not so much from a technical/architectural perspective but simply from a project viability perspective. I can't effectively argue the technical de/merits of the decisions to date <i>(although the new approach towards of deriving from a Float if you want "Floatish" behaviour makes more sense to me, and I have never seen an effective rebuttal to Leo's posts regarding the problems with continuations/registers)</i> but I also feel that it is largely irrelevent. As long as there are no feature gaps for target languages and assuming that we meet (at a very minimum) Perl5 performance then I don't give a crap. </p><p> I trust there are enough eyes on the project that decisions taken will not prove disastrous. Having the head honcho and the lead developer on the same page is a very good thing<nobr> <wbr></nobr>...</p> milardj 2005-06-13T15:23:31+00:00 journal IE Leak Detector <a href=""></a> milardj 2005-06-07T21:10:09+00:00 journal Must Reads - Blogs I follow 40 or so technical blogs but there are 3 that I check faithfully every day:<ul> <li>Sam Ruby <a href=""></a></li> <li>Patrick Logan <a href=""></a></li> <li>Koranteng Ofosu-Amaah <a href=""></a></li> </ul><p> Check them out if you don't already have them bookmarked and please let me know if you have any favourites that touch on dynamic languages, web programming, configuration management, or design.</p> milardj 2005-05-18T14:29:33+00:00 journal Summer Reading Suggestions Some books that I've read or reread recently that deserve a larger audience (all links to <ul> <li>White Teeth by Zadie Smith: a major talent. She was in her early to mid twenties when she wrote this book and it just blew me away.<br> <a href=""></a> </li><li>The Brother's K|The River Why? - by David James Duncan: these are older books but I've reread each one at least 3 times. Don't be put off by the length of Brother's K<br> <a href=""></a> <a href=""></a> </li><li>Malazan Book of the Fallen (Series) by Steven Erikson - it's hard to to take away from George Martin but *this* might be the best fantasy series around. Take the money you were going to spend on Jordan's next piece of crap and buy Gardens of the Moon instead. You might find it tough going at first but if you stick with it you will be well rewarded. <br> <a href=""></a> </li><li>Witch Blood by Wil Shetterly - this is an oldie (mid 80's) but well worth looking for. With less pages then a typical Robert Jordan prologue it has more action the Jordan has written since volume 4 or 5 of the Great Wheel. Find this book!<br> <a href=""></a> </li><li>The Guards|The Killing of the Tinkers by Ken Bruen - short on plot but miles upon miles of style, atmosphere, and characterization. If Chandler and Lehane had an Irish love child that was beaten up by Jim Thompson - his name would be Ken Bruen (no offence pudge - I realize that Chandler and Lehane are both men but I wasn't suggesting marriage - just speaking metaphorically)<br> <a href=""></a> </li><li>The Club Dumas (or anything he has written) by Arturo Perez-Reverte - the Club Dumas was made into a movie starring Johnny Depp but don't let that stop you. I'm usually slightly disappointed by Reverte's endings but the rest of the book always makes up for it.<br> <a href=""></a> </li></ul> milardj 2005-05-13T15:38:52+00:00 journal Kitchen Sink Language I sporadically follow discussions on lambda (I'm not a PHD but I play one on TV) and while Parrot seems to be *legitimate* in the minds of most lambdaheads Perl6 is openly sneered at. <p> Perl6 is a <cite>kitchen sink language</cite> and <cite>lack[s] elegance or conceptual consistency</cite> and there is <cite>some really ugly stuff planned for Perl6</cite>. It probably doesn't matter because <cite>the language spec is so complex it would be a wonder if it is ever fully implemented</cite> (I'm sure Autrijus would concur with that - given his slow progress to date). But all is not bleak with Perl6 design because <cite>[o]ccasionally it stumbles across a good idea, in the same way that a construction worker might unearth a fossil when drives his pickaxe through it.</cite> Ok not exactly a rave but I guess if we trim a bit of context then we might get a good review: </p><p> Perl6 has "[snip][snip][snip][snip][snip][snip][snip][snip][snip][snip][snip][snip]good idea[s] [snip][snip][snip][snip][snip][snip][snip][snip]". </p><p> Score one for @Larry. </p><p> The flaws in Perl6 design (they aren't really pointed out beyond broad generalities but I'm sure it must be flawed) are most likely due to @Larry's alcohol issues - being a responsible Canadian I've already called every bar, restaurant, licqour|beer store in the greater GTA so there will be no alcohol served to @Larry during YAPC - I REFUSE TO BE AN ENABLER - no more <cite>drunken meanderings</cite> for @Larry. </p><p> I've also started a collection to send @Larry[0] to Lourdes in order to cure his vision issues - no longer will Perl 6 design docs be equated to a <cite>blind man's account of constructing a puzzle</cite>. PRAISE THE LORD and pass the compiler! </p><p> I have a solution to Perl6's image issues. I think everything can be solved with a strategic renaming. Perhaps if the 1.0 press release reads: "After years of effort we are pleased to release version 1.0 of<nobr> <wbr></nobr>........... ARC", then like CSN&amp;Y and an entire birkenstock-wearing, barbershop-fearing, and recreational-drug-using generation we would be <cite>golden</cite>. Or we can change Larry's name to Larry von Wall. Whatever. </p><p> Anyway<nobr> <wbr></nobr>... keep up the good work everyone and maybe one day Frank Atanassow will finally say: "Perl6? You know what it almost is an improvement on sh" or at least "Perl6? At least it's not Perl5". </p><p> References <a href=""></a> <br> <a href=""></a> <br> <a href=""></a> <br> <a href=""></a> <br> <a href=""></a></p> milardj 2005-05-13T15:00:35+00:00 journal No 'Louie Louie' FOR YOU!! Band Banned From Performing 'Louie Louie'<br> <a href=""></a> <p> <cite>Dawning said "Louie Louie" was not appropriate for Benton Harbor students to play while representing the district &#8212; even though the marching band wasn't going to sing it.</cite> </p><p> And my favourite<nobr> <wbr></nobr>...</p><p> <cite> The best-known, most notorious version was a hit in 1963 for the Kingsmen; the FBI spent two years investigating the lyrics before declaring they not only were not obscene but also were "unintelligible at any speed." </cite> </p><p> Two years!</p> milardj 2005-05-05T19:58:59+00:00 journal Does Randal drink single-malt scotch ... From Saturdays Globe and Mail (couldn't find an online link) talking with Neil Bauman about Geek Cruises: <p> <cite> Okay, so who parties the hardest? According to Bauman, those who use Perl, a Web programming language. "They're a bright group of people. They like single-malt scotch and they're connoisseurs of beers." </cite></p> milardj 2005-04-25T13:05:53+00:00 journal Whuffie in Action Cory Doctorow wrote a book called <strong>Down and Out in the Magic Kingdom</strong> which won the Locus and was nominated for a Nebula. Cory releases all his work under the Creative Commons license so follow the link if you want to download and read. <p> Down and Out takes place in a post-scarcity/post-mortality universe. Post-scarcity because basic human needs are met for all; post-mortality through cloning and brain backups. This isn't a book review (I was slightly underwhelmed but not to the point that I wouldn't read more from him) but I bring this all up because I see Cory's concept of <em>Whuffie</em> (think karma) all around me. </p><p> Autrijus has amassed so much whuffie in the past two months I would put him (not sure of the proper pronoun as a writeup of a perl golfing tourney kept referring to "her" and everyone else to "him" - I'll be able to settle this at YAPC::NA if no one sets me straight before then) as Thor to Larry's Odin and Damian's Loki (for the trickster aspect not the evil aspect - natch). </p><p> That doesn't mean that Autrijus has done more for the perl community then Tom C/Chip/Dan/Leo/Pierre/Alison/Luke/MJD/Damian or a dozen other good candidates. It doesn't mean that Autrijus is smarter then other people - it means that Autrijus started something that resonated with a lot of people and they repayed him in the new currency: respect. </p><p> What did Autrijus do? He started Pugs sure but more importantly he started his own tribe (an anarchist-collective of ADD/OCD/gay/straight/thumbed/thumbless/ritalin-taking/wage-slave/self-employed hackers - all hackers in spirit if not all necessarily in skill). Even more importantly I think Autrijus threw a virtual coffee cup against the wall and reenergized a community that desperately needed it. We don't need to wait for Perl6 - it's here right now. People are hacking in it now and exposing both warts and beauty marks. </p><p> I didn't mean this as another paean to the pugs-tribe but I've been thinking about whuffie lately. I've been watching as python-whuffie has been increasing as perl-whuffie has been steadily eroding. Surf lambda for a while, and though extreme, you'll get a pretty good sense of what perl-whuffie is like outside of our community. Loving Perl is starting to resemble an 80's John Hughes movie - really digging this girl but slightly embarrased about it and afraid you're friends will find out. </p><p> Which is a shame, because just like in that John Hughes movie (or think of Better Off Dead where John Cusack doesn't seem to notice that the hot french foreign exchange student is<nobr> <wbr></nobr>... well<nobr> <wbr></nobr>.. hot) I am so excited about what @Larry has done with P6. There are things I don't agree with, and there are lots of things I still don't understand, but damn that hot french foreign exchange student is<nobr> <wbr></nobr>... well<nobr> <wbr></nobr>... hot. </p><p> Where Guido is removing features form Python so that developers don't have to think too much (that's almost a direct quote) I'm glad that the swiss army chainsaw is<nobr> <wbr></nobr>... cue Mike Myers impersonation<nobr> <wbr></nobr>... <em>going nuclear, BABY!</em></p> milardj 2005-04-07T18:18:43+00:00 journal Wanker Hmmm.. haven't used that since my punk (MDC/Crass/Blitz/Clash/DK/Partisans still come to mind) days but it seems to fit<nobr> <wbr></nobr>... <p> Frank Atanassow writes: </p><p> <cite> I've looked at the Perl apocalypses and they are hardly more than a scatter-brained enumeration of trivia and faux pas; it reads like a blind man's account of constructing a puzzle. It doesn't solve problems by solving problems; it's a misadventure in stochastic symbol-pushing. Perl 6 is just another iteration in that language's interminable and drunken meandering. Occasionally it stumbles across a good idea, in the same way that a construction worker might unearth a fossil when drives his pickaxe through it. According to you, I guess "we can regard him as" a paleontologist, then. </cite> </p><p> </p><p> <cite>(I'm sorry but I really need to get this off my chest, again:) Scripting languages thrive on hype because they have no other advantage; their advantage is the hype, and the popularity which accompanies it. Sure, Perl may be an improvement on sh (frankly, I am not so sure<nobr> <wbr></nobr>:) but it is hard to find a strawer man. </cite> </p><p> </p><p> 1 will get you 10 that this guy is doing his PHD or first of many post doc's and has never held a real job<nobr> <wbr></nobr>... </p><p> All theory and no practice<nobr> <wbr></nobr>...</p> milardj 2005-04-06T18:52:52+00:00 journal The King is Dead! Long Live the King! Dan has officially stepped down as Parrot designer and has been replaced by Chip Salzenburg.<p>As anyone following parrot knows Dan has been MIA for the last few months so this is definitely overdue. I'm hoping that parrot will experience the revitalization and excitement that Perl6-Language has recently experienced (oh for the last 48 days or so).</p><p> Many, many thanks to Dan for all his work and many thanks to Chip for taking on the burden. </p><p> Now we just need to figure out a way to lock Leo, Chip, Autrijus, Sam Ruby, and @Larry in a room for a couple of weeks<nobr> <wbr></nobr>...</p> milardj 2005-03-21T21:20:50+00:00 journal Parrot Roadmap It looks like Will Coleda has picked up the ball to put together a roadmap for Parrot (or at least to facilitate the creation). <br> <a href=""></a> <br> Many thanks Will. milardj 2005-01-24T16:25:12+00:00 journal Homage to Simon Cozens Perl6-o-meter++ <a href=""></a> <p> Perl6-o-meter-- <a href=""></a> </p><p> Updated links. Thanks</p> milardj 2005-01-07T15:18:16+00:00 journal RIP: Will Eisner Will Eisner <a href=""></a> died on January 3rd. For those who have never heard of Will he created comic books and IMO the best comic to be distributed by newspapers: the 16 page supplement following the adventures of <b>The Spirit</b>. <p> Starting in the late 70's and continuing until his death Will also pioneered the creation of literaty graphic novels(in North America - Asia and Europe have never had the "comics are for kids" stigma prevalent here) </p><p> Will was an inspiration for multiple generations of comic artists and his work done 60-70 years ago holds up remarkably well today. </p><p> This weekend I need to wipe the cobwebs off of my comic collection and find the Kitchen Sink reprints of The Spirit and spend some time with an old friend. </p><p> Rest in peace.</p> milardj 2005-01-06T15:47:34+00:00 journal Is Parrot going to self-destruct? <p>IMO the most important project in the perl world currently is Parrot. I love what I am seeing Perl6 evolve into (well most of it anyway) but it is Parrot that could evolve into the "killer" platform of the next decade.</p><p>I read quite a few technical blogs and it is amazing how much movement there is towards dynamic languages. The number of heavyweights who are extolling the virtues of Python and Ruby is pretty impressive.</p><p>I really see a great future for dynamic languages in the next decade and Parrot, if it is successful, could become the de facto standard.</p><p>Note the qualification. Will Parrot be successful? I'm starting to have my doubts. I could just as easily see the project flame-out in acrimony.</p><p>In the past month or two I've sometimes found it painful to follow the internals list because:</p><p>a) the same arguments are repeated endlessly<br>b) the animosity between the lead developers<br>c) the general black tone of some posts</p><p>I think part of the problem is that Dan has been pretty much out of touch for the last while. That's no slam against Dan because I have nothing but admiration for people working a full time job and essentially working a second full time job (Parrot) for the benefit of all of us. But I do believe it is hurting the project.</p><p>What is needed IMO is a clear roadmap of what is remaining, what is the design for what is remaining, what is the precedence and dependencies for the remaining tasks. This might exist already but if it does I see no evidence that it is being followed.</p><p>Does anyone have a good feel for where Parrot is in terms of completeness? Anyone else share my uneasiness with the interpersonal dynamics of peope working on the project?</p><p>I feel a bit hypocritical for sitting back and pointing my finger at the problems when I'm doing nothing to help on the project but I truly want parrot to succeed and I'm starting to wonder if it will.</p><p>NOTE: by "succeed" I mean widespread adoption by Ruby, Python et al developers and not simply a Perl6 VM.</p> milardj 2005-01-04T15:34:29+00:00 journal My pet solution: Web framework <p> Amongst other things I intend to use this journal to discuss the design of existing and new projects and frameworks I have worked on. I tend to design in a vacuum these days (at my old job I was usually hooked up with a partner during design which I found to be educational and led to stronger designs - we both approached the problem from different angles and the design really benefited from that) and I miss having a feedback loop to point out missed opportunities and more effective strategies. </p><p> I'm a full time programmer who also operates a consulting/contracting company (very small scale) on the side. About 2 1/2 years ago I was contracted to create a web app which would allow: </p><ul> <li>Uploading of data files (typically market research results) into a database</li> <li>Definition and generation of crosstab reports</li> <li>Definition and generation of regular reports</li> <li>Project, user, and client management</li> </ul><p> I decided on a framework that would be driven by XML. I borrowed the run mode concept from C::A and defined an XML file that would control the "steps" needed for each run mode: </p><blockquote><div><p> <tt>&nbsp; &nbsp; &lt;rm name="login" next="main.html" on-error="login.html"&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;step handler="login"/&gt;<br>&nbsp; &nbsp; &lt;/rm&gt;</tt></p></div> </blockquote><p>"steps" could be predefined sql actions (see below) or delegated to a handler as shown above. "handlers" are defined in another xml file and are subroutines that are passed the CGI instance and the database handle:</p><blockquote><div><p> <tt>&lt;handler name="login"&gt;<br>&nbsp; &nbsp; sub {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;my ($cgi,$dbh) = @_;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;#-- Do some stuff<br> <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return $cgi;<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&lt;/handler&gt;</tt></p></div> </blockquote><p> I decided on this approach because I found that a lot of the perl code I needed as handlers were only a couple of lines long and I didn't feel the need to create a package. </p><p> In a questionable decision I decided to just pass the CGI instance throughout the framework. Any part of the framework could add new params to the instance or modify existing params. At the very least I should have created a wrapper to CGI. That is one of the items on my To Do list. </p><p> As mentioned previously "steps" could also be predefined SQL actions:</p><blockquote><div><p> <tt>&nbsp; &nbsp; &lt;rm name="foo_search" next="foo.html"&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;step type="get" action="get_foo" using="foo_table.xml"/&gt;<br>&nbsp; &nbsp; &lt;/rm&gt;</tt></p></div> </blockquote><p>Where foo_table.xml contains all the SQL related to the foo table:</p><blockquote><div><p> <tt>&lt;sql name="get_foo"&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &lt;statement&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Select col1, col2, col3 from foo<br>&nbsp; &nbsp; &nbsp; &nbsp; &lt;/statement&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &lt;where&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;where x = ? and y = ? and z= ?<br>&nbsp; &nbsp; &nbsp; &nbsp; &lt;/where&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &lt;values&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;column db_name="col1" alias="cgi_param_name1"/&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;column db_name="col2" alias="cgi_param_name2"/&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;column db_name="col3" alias="cgi_param_name3"/&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &lt;/values&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &lt;bind&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;column alias="x_alias"/&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;column alias="y_alias"/&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;column alias="z_alias"/&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &lt;/bind&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &lt;struct alias_key="col1+col2" type="nested" cgi_param="foo_struct"/&gt;<br>&nbsp; &nbsp; &lt;/sql&gt;</tt></p></div> </blockquote><p> When (the module which processes the run modes) sees a SQL step (type = get|delete|insert|update) it calls which is responsible for database interactions. DAO will execute the SQL and determine how to bundle up the result set. In this case because we defined the </p><blockquote><div><p> <tt>&lt;struct&gt; </tt></p></div> </blockquote><p> tag we are telling DAO that we want a more complex data structure returned. The struct tag instructs to return a hash where the key is the concatenation of the columns defined by the key attribute. The structure would be passed in $cgi with the param name "foo_struct" as defined by the cgi_param attribute in the </p><blockquote><div><p> <tt>&lt;struct&gt;</tt></p></div> </blockquote><p> tag. </p><p> If our result set is:</p><blockquote><div><p> <tt>COL1&nbsp; &nbsp; &nbsp; COL2&nbsp; &nbsp; COL3<br>AAAA&nbsp; &nbsp; &nbsp; 11111&nbsp; &nbsp;11111<br>AAAA&nbsp; &nbsp; &nbsp; 22222&nbsp; &nbsp;12121</tt></p></div> </blockquote><p>Then our return structure is:</p><blockquote><div><p> <tt>{ "AAAA~11111" =&gt; { "COL1" =&gt; AAAA<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "COL2" =&gt; 11111<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "COL3" =&gt; 11111 },<br>&nbsp; "AAAA~22222" =&gt; { "COL1" =&gt; AAAA<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "COL2" =&gt; 22222<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "COL3" =&gt; 12121}<br>}</tt></p></div> </blockquote><p>If we specify type="nested" then the return structure is:</p><blockquote><div><p> <tt>{<br>&nbsp; &nbsp; "AAAA" =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 11111 =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "COL1" =&gt; AAAA<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "COL2" =&gt; 11111<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "COL3" =&gt; 11111<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;},<br> <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 22222 =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "COL1" =&gt; AAAA<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "COL2" =&gt; 22222<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "COL3" =&gt; 12121<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>}</tt></p></div> </blockquote><p> By default, if no </p><blockquote><div><p> <tt>&lt;struct&gt;</tt></p></div> </blockquote><p> tag is defined, then each column is added to the $cgi instance where param name is equal to the alias attribute. </p><p> Run mode definitions can also import other defined run modes:</p><blockquote><div><p> <tt>&nbsp; &nbsp; &lt;rm name="something_common"&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;step handler="always_need_this"/&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;step handler="and_this"/&gt;<br>&nbsp; &nbsp;&lt;/rm&gt;<br>&nbsp; &nbsp; &lt;rm name="foo_search" next="foo.html"&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;step type="get" action="get_foo" using="foo_table.xml"/&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;step include="something_common"/&gt;<br>&nbsp; &nbsp; &lt;/rm&gt;</tt></p></div> </blockquote><p>We can also iterate run modes (or steps) when needed. For example say we have a multi select box and we want to execute a step for each highlighted option:</p><blockquote><div><p> <tt>&lt;rm name="delete_user" foreach="delete_user_list" set="user_id" next="userMgr.html"&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &lt;step type="delete" action="delete_user" using="user_table.xml"/&gt;<br>&nbsp; &nbsp; &lt;/rm&gt;</tt></p></div> </blockquote><p> This run mode will iterate through $cgi-&gt;param("delete_user_list") set $cgi-&gt;param(-name=&gt;"user_id", -value=&gt;current id) and perform a delete for each user. </p><p> We can also iterate at the step level if some steps have to be executed for a list and some only once:</p><blockquote><div><p> <tt>rm name="delete_user" next=" userMgr.html"&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &lt;step foreach="delete_user_list "<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; set="user_id"<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;type="delete"<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;action="delete_user"<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; using="user_table.xml"/&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &lt;step handler="foobar"/&gt;<br>&nbsp; &nbsp; &lt;/rm&gt;</tt></p></div> </blockquote><p> So in summary - every interaction with the server is defined by a run mode. A run mode can consist of 0 or more steps (if 0 then we are essentially only setting the next page to serve up). Each step can consist of a predefined database interaction or be delegated to a handler. </p><p> I've found this to work very well for my purposes and I've been able to add many screens without having to write any new code at all. The SQL xml files are auto-generated by another program I wrote so some new screens (for example search/result/detail screens) can be created by simply defining the templates and by defining the run modes and steps. Since they all follow the same pattern I simply copy the existing run modes, change the template name, change the action names, and I'm done. </p> milardj 2004-12-22T02:35:14+00:00 journal