<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:iweb="http://www.apple.com/iweb" version="2.0">
  <channel>
    <title>Harry Gates’ blog</title>
    <link>http://www.perly-gates.com/The_Perly-Gates/Essbase_%26_Perl/Essbase_%26_Perl.html</link>
    <description>A blog to share my use of Perl in automating Essbase applications.</description>
    <generator>iWeb 2.0.4</generator>
    <item>
      <title>Essbase_Perl.pm LibXML update</title>
      <link>http://www.perly-gates.com/The_Perly-Gates/Essbase_%26_Perl/Entries/2009/3/27_Essbase_Perl.pm_LibXML_update.html</link>
      <guid isPermaLink="false">ce1086e0-f204-4832-85b3-29d1ab861a26</guid>
      <pubDate>Fri, 27 Mar 2009 09:54:47 -0400</pubDate>
      <description>I have significantly rewritten the subroutine in Essbase_Perl.pm that reads the XML configuration file. It now uses the &lt;a href=&quot;http://search.cpan.org/dist/XML-LibXML&quot;&gt;XML::LibXML Perl module&lt;/a&gt; instead of XML::Simple.  I made this design decision for 2 reasons.&lt;br/&gt;&lt;br/&gt;First, XML::Simple uses internal Perl data storage mechanisms.  Those with even the slightest acquaintance with Perl hashes and arrays know of their power and simplicity.  However, they suffer from one major flaw when used in conjunction with XML.  They do not retain the original order of XML nodes.  This is why the original config_load.xml had the rather klunky num=&quot;1&quot; numbering system for each command.  Without explicitly specifying the order of commands in the xml configuration file, XML::Simple would have run them in whatever seemingly-random order they were stored by Perl's hashes and arrays.  Obviously this could be a problem.  After all, you wouldn't want to calc your database before even loading it, now would you?&lt;br/&gt;&lt;br/&gt;LibXML is written in C, so it is immune from this particular peculiarity of Perl's processing &amp;lt;wipe spit off monitor here if reading aloud&gt;.  The order of commands you specify in config_load.xml is now the order in which the commands will be executed.  No kludgy command numbering system is required.&lt;br/&gt;&lt;br/&gt;Getting rid of the command numbering is a MAJOR advantage, as I soon found out when I had to add a command #35 in the middle of an xml section containing 100 commands.  With the old XML::Simple version of Essbase_Perl.pm I had to manually renumber the commands after the new command #35. That meant changing the old num=&quot;35&quot; to num=&quot;36&quot;, the old num=&quot;36&quot; to num=&quot;37&quot;, the old num=&quot;38&quot; to num=&quot;39&quot;...  I think you get the point.  Not a lot of fun.  With the LibXML version, however, I simply inserted the new command where it needed to go and that was that.  No muss, no fuss.&lt;br/&gt;&lt;br/&gt;The second reason I made the decision to use LibXML instead of XML::Simple can be summed up in one word: speed.  Because it's implemented in C, LibXML is lightning fast.  &quot;Well&quot;, you might be thinking, &quot;my xml configuration file is only a couple hundred lines long - at most, so we're only talking nanoseconds of difference here&quot;; and you'd be right.&lt;br/&gt;&lt;br/&gt;The speed factor really only comes into play when you're reading and writing very large xml files - with tens or hundreds of thousands of lines.  And this is exactly the situation I found myself in with one client recently.  I needed to read a huge xml file (we're talking several gigabytes in size here) exported from a certain ornery GL, which shall remain nameless (&amp;lt;cough&gt;PeopleSoft&amp;lt;/cough&gt;).  XML::Simple was choking on the file.  LibXML, on the other hand, processed the whole file in 5 minutes.  Needless to say, I am now a LibXML convert.&lt;br/&gt;&lt;br/&gt;Due to other improvements of using LibXML, the structure of the &quot;General&quot; section of config_load.xml has also been changed.  Here's a sample of what it now looks like:&lt;br/&gt;&lt;br/&gt;&amp;lt;General&gt;&lt;br/&gt;&amp;lt;desc&gt;use this section to set general variables for use throughout the load&amp;lt;/desc&gt;&lt;br/&gt;&amp;lt;variable name=&quot;EssUser&quot;&gt;harry&amp;lt;/variable&gt;&lt;br/&gt;&amp;lt;variable name=&quot;EssPwd&quot;&gt;rules&amp;lt;/variable&gt;&lt;br/&gt;&amp;lt;/General&gt;&lt;br/&gt;&lt;br/&gt;Previously it looked like:&lt;br/&gt;&amp;lt;General&gt;&lt;br/&gt;&amp;lt;desc&gt;use this section to set general variables for use throughout the load&amp;lt;/desc&gt;&lt;br/&gt;&amp;lt;EssUser&gt;harry&amp;lt;/EssUser&gt;&lt;br/&gt;&amp;lt;EssPwd&gt;rules&amp;lt;/EssPwd&gt;&lt;br/&gt;&amp;lt;/General&gt;&lt;br/&gt;&lt;br/&gt;I prefer the new way (using &quot;variable&quot;).  It makes it crystal clear that we're setting user-defined variables here, not simply populating some kind of predefined, Essbase_Perl.pm options.&lt;br/&gt;&lt;br/&gt;So, without further eloquence, here is the modified Essbase_Perl.pm code:&lt;br/&gt;use XML::LibXML;&lt;br/&gt;sub readXMLConfig {&lt;br/&gt;       my ($xml) = @_;&lt;br/&gt;&lt;br/&gt;      my ($return, @msgs, $start, $sec_start);&lt;br/&gt;&lt;br/&gt;      $parser = XML::LibXML-&gt;new();&lt;br/&gt;&lt;br/&gt;      # Check for well-formedness, stop if issue:&lt;br/&gt;      eval {$parser-&gt;parse_file($xml);};&lt;br/&gt;      &amp;amp;errHandler(1, &quot;issue with $xml config file&quot;, $@) if ($@);&lt;br/&gt;&lt;br/&gt;      $doc = $parser-&gt;parse_file($xml);&lt;br/&gt;&lt;br/&gt;      print &quot;following is the $xml config file at the time of the load:\n&quot;;&lt;br/&gt;      print $doc-&gt;toString;&lt;br/&gt;      #print Dumper($doc) . &quot;\n&quot;;&lt;br/&gt;&lt;br/&gt;      my $date = scalar localtime(time);&lt;br/&gt;      my $start_load = time;&lt;br/&gt;&lt;br/&gt;      print &quot;\n\nstarting load process at $date\n&quot;;&lt;br/&gt;&lt;br/&gt;   #set variables from General section of config_load.xml file  &lt;br/&gt;    foreach my $general ($doc-&gt;findnodes('//General/variable')) {&lt;br/&gt;        $vars{$general-&gt;getAttribute('name')} = $general-&gt;textContent;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    my $dbh = &amp;amp;Ess_connect($vars{EssUser}, $vars{EssPwd});&lt;br/&gt;&lt;br/&gt;    foreach my $order ($doc-&gt;findnodes('//Run_Order/command')) {&lt;br/&gt;        my $sec = &quot;//&quot; . $order-&gt;textContent;&lt;br/&gt;        my $app = $doc-&gt;findvalue($sec . &quot;/application&quot;);&lt;br/&gt;        my $db = $doc-&gt;findvalue($sec . &quot;/database&quot;);&lt;br/&gt;        my $section = $sec . &quot;/command&quot;;&lt;br/&gt;        my $sec_start = time;&lt;br/&gt;        print &quot;\n##################Section is: &quot; . $order-&gt;textContent . &quot;#######################################\n&quot;;&lt;br/&gt;        my $i = 1;&lt;br/&gt;&lt;br/&gt;        foreach my $config ($doc-&gt;findnodes($section)) {&lt;br/&gt;            print &quot;\nrunning command #&quot; . $i . &quot;\n&quot;;&lt;br/&gt;            my $type = $config-&gt;getAttribute('type');&lt;br/&gt;&lt;br/&gt;            &amp;amp;runCommand($type, $config, $app, $db, $dbh);&lt;br/&gt;            $i++;&lt;br/&gt;        }&lt;br/&gt;         my $sec_elapsed = &amp;amp;Elapsed($sec_start, time);&lt;br/&gt;         print &quot;$section completed in $sec_elapsed\n&quot;;&lt;br/&gt;         print &quot;####################$sec completed successfully############################################\n&quot;;&lt;br/&gt;         &amp;amp;sendMsg($err_to, $vars{notification_from}, &quot;completed $sec&quot;, &quot;completed $sec successfully in $sec_elapsed&quot;, &quot;&quot;);&lt;br/&gt;    }&lt;br/&gt;      Ess_disconnect($dbh);&lt;br/&gt;      print &quot;Successfully completed.  Processing took: &quot; . &amp;amp;Elapsed($start_load, time) . &quot;\n&quot;;&lt;br/&gt;      &amp;amp;sendMsg($vars{notification_to}, $vars{notification_from}, &quot;Successfully completed Essbase processing in: &quot; .     &amp;amp;Elapsed($start_load, time), &quot;&quot;, &quot;&quot;);&lt;br/&gt;      #&amp;amp;notify;&lt;br/&gt;}&lt;br/&gt;</description>
    </item>
    <item>
      <title>Update</title>
      <link>http://www.perly-gates.com/The_Perly-Gates/Essbase_%26_Perl/Entries/2009/1/21_Update.html</link>
      <guid isPermaLink="false">96d3cb5b-462f-41b6-aa3c-aeede32285fe</guid>
      <pubDate>Wed, 21 Jan 2009 19:39:48 -0500</pubDate>
      <description>I haven’t had much time lately to work on the Essbase_Perl.pm module.  I started a new job at a consulting company recently and have been extremely busy.  Most of the work I will be doing for the next couple of months is Excel VBA-related.  I have, however, done several installs of Essbase 11.1.1 - both on Windows and Linux - for clients.&lt;br/&gt;&lt;br/&gt;The first step, of course, is to download the Linux version of EPM 11.1 from &lt;a href=&quot;http://edelivery.oracle.com/&quot;&gt;Oracle’s website&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;The new installer works the same on both platforms, but there are several things to watch out for on Linux.  Hopefully when I get more time, I’ll be able to post some more details.&lt;br/&gt;&lt;br/&gt;I was unable to get the EAS (Essbase Administration Server), the program, not the service, to run on Linux.  I can’t tell from Oracle’s documentation whether EAS is supported on Linux.  Does anyone know?</description>
    </item>
    <item>
      <title>Binaries of Essbase.pm compiled for win32</title>
      <link>http://www.perly-gates.com/The_Perly-Gates/Essbase_%26_Perl/Entries/2008/9/3_Binaries_of_Essbase.pm_compiled_for_win32.html</link>
      <guid isPermaLink="false">ebf8ebc9-78ba-4364-8124-49f7d5e38b54</guid>
      <pubDate>Wed, 3 Sep 2008 11:00:32 -0400</pubDate>
      <description>There seems to be great demand for binaries of the Essbase.pm compiled for Windows.  Therefore, I am making mine available.  I am using &lt;a href=&quot;http://www.activestate.com/Products/activeperl/feature_list.mhtml&quot;&gt;ActivePerl 5.10.0&lt;/a&gt; for MSWin32-x86.  The binaries below work for me on Windows XP SP2 and Windows 2000 SP4.  I used Microsoft Visual C++ 6.0 to compile them.&lt;br/&gt;&lt;br/&gt;If you have installed ActivePerl with the defaults, Perl should be located under C:\Perl.  Given that, here is where the files need to go:&lt;br/&gt;&lt;br/&gt;under C:\Perl\site\lib&lt;br/&gt;&lt;a href=&quot;Entries/2008/9/3_Binaries_of_Essbase.pm_compiled_for_win32_files/essbase.pm&quot;&gt;essbase.pm&lt;/a&gt;&lt;br/&gt;under C:\Perl\site\lib\auto\Essbase&lt;br/&gt;&lt;a href=&quot;Entries/2008/9/3_Binaries_of_Essbase.pm_compiled_for_win32_files/Essbase.dll&quot;&gt;Essbase.dll&lt;/a&gt;&lt;br/&gt;&lt;a href=&quot;Entries/2008/9/3_Binaries_of_Essbase.pm_compiled_for_win32_files/Essbase.exp&quot;&gt;Essbase.exp&lt;/a&gt;&lt;br/&gt;&lt;a href=&quot;Entries/2008/9/3_Binaries_of_Essbase.pm_compiled_for_win32_files/Essbase.bs&quot;&gt;Essbase.bs&lt;/a&gt;&lt;br/&gt;&lt;a href=&quot;Entries/2008/9/3_Binaries_of_Essbase.pm_compiled_for_win32_files/Essbase.lib&quot;&gt;Essbase.lib&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;That’s it.  It’s really not that hard.  And it’s definitely worth the effort, because once you have the Essbase Perl module installed and working, you can start using my &lt;a href=&quot;Entries/2008/8/24_Essbase_load_program_unveiled.html&quot;&gt;Essbase_Perl.pm&lt;/a&gt; to make your life much easier.</description>
    </item>
    <item>
      <title>Essbase_Perl.pm subroutines (sending email notifications and disconnecting)</title>
      <link>http://www.perly-gates.com/The_Perly-Gates/Essbase_%26_Perl/Entries/2008/8/27_Essbase_Perl.pm_subroutines_%28sending_email_notifications_and_disconnecting%29.html</link>
      <guid isPermaLink="false">98a25ccb-7bc9-4952-a982-a5eb93cca15b</guid>
      <pubDate>Wed, 27 Aug 2008 11:05:02 -0400</pubDate>
      <description>Previously we reviewed how the &lt;a href=&quot;Entries/2008/8/27_Essbase_Perl.pm_subroutines_%2528sending_email_notifications_and_disconnecting%2529_files/Essbase_Perl-2.pm&quot;&gt;Essbase_Perl.pm&lt;/a&gt; handles errors.  It’s not enough, however, just to identify an error and stop the program from proceeding.  Wouldn’t it be great to have the program send an email notifying a designated person (and let’s face it, it’s us, the lowly Essbase admin) to take a look at the issue?&lt;br/&gt;&lt;br/&gt;As most of the Essbase loads I’ve been involved with are set to run overnight, this facility is a godsend.  No longer do I have to sit up all night babysitting my Essbase loads.  No, sir.  Now I can sleep like a baby, knowing that any errors will be sent to my trusty BlackBerry, which has been preset to emit an ear-piercing shriek whenever it receives an error email from Essbase_Perl.  Enough talking.  Let’s dive into the code.&lt;br/&gt;&lt;br/&gt;sub sendMsg { &lt;br/&gt;   my ($to, $from, $subject, $message, $file) = @_; &lt;br/&gt;  &lt;br/&gt;    my $msg = MIME::Lite-&gt;new( &lt;br/&gt;    From =&gt; $from, &lt;br/&gt;    To =&gt; $to, &lt;br/&gt;    Subject =&gt; $subject, &lt;br/&gt;    Data =&gt; $message &lt;br/&gt;   ); &lt;br/&gt;  &lt;br/&gt;   if (defined ($file) and ($file ne &quot;&quot;)) { &lt;br/&gt;      my @files = split(/,/, $file); &lt;br/&gt;      &lt;br/&gt;      foreach my $f (@files) { &lt;br/&gt;          $msg-&gt;attach( &lt;br/&gt;          Type =&gt; &quot;text/plain&quot;, &lt;br/&gt;          Path =&gt; $file, &lt;br/&gt;          Filename =&gt; $file, &lt;br/&gt;          Disposition =&gt; &quot;attachment&quot; &lt;br/&gt;         ); &lt;br/&gt;         print &quot;attached file: $file\n&quot;; &lt;br/&gt;   } &lt;br/&gt; } &lt;br/&gt;  &lt;br/&gt;   MIME::Lite-&gt;send('smtp', 'enter_name_of_mail_server_here', Timeout =&gt; 60); &lt;br/&gt;   my $ret = $msg-&gt;send(); &lt;br/&gt;   return 0 if $ret == 1; &lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;In order for the subroutine above to work, you will need to add a reference to the MIME Lite module in your Perl file, like so:&lt;br/&gt;&lt;br/&gt;use MIME::Lite;&lt;br/&gt;&lt;br/&gt;Clear as mud?  Let’s see if I can make a little sense out of it for you.  The first line is getting the parameters.  As you can see, the ‘to’ email address, the ‘from’ address, the ‘subject’, body, and any files to be attached are passed in by the calling subroutine.&lt;br/&gt;&lt;br/&gt;So what, Harry, does the following line do?  &lt;br/&gt;&lt;br/&gt;if (defined ($file) and ($file ne &quot;&quot;)) {&lt;br/&gt;&lt;br/&gt;Sometimes you don’t want, or need, to attach files to the email message.  In this case the $file variable will be empty.  If that’s the case, there’s no reason to run the code to attach each file.  If, however, you would like to attach log files, for example, containing the errors, you can pass them as a comma-delimited string into the $file variable.&lt;br/&gt;&lt;br/&gt;That’s where the @files array comes into play.  It takes the comma-delimited string and splits it into an array.  The next line, beginning with ‘foreach’, loops through each value in the array, representing a filename, and attaches it to the email.  The last few lines send the email.&lt;br/&gt;&lt;br/&gt;One thing to remember, however. is to change ‘enter_name_of_mail_server_here’ to whatever your company’s mail server is.  An example would be ‘mail.mycompany.server’.  Basically, it can be just about anything that your email administrator can dream up.  It’s best just to find him and ask.&lt;br/&gt;&lt;br/&gt;Finally, after running your program (with no errors, I’m sure), you’ll want to disconnect from Essbase.  Otherwise, you could have some orphaned processes floating around on your Essbase server.  And we can’t have that, can we?  Thankfully, the Essbase.pm module from Hyperion provides a function specifically for disconnecting.&lt;br/&gt;&lt;br/&gt;sub Ess_disconnect {&lt;br/&gt;        my ($dbh) = @_;&lt;br/&gt;	print $dbh-&gt;disconnect() == $Essbase::MAXL_STATUS{NOERR} ?&lt;br/&gt;	    &quot;ok: Disconnect from Essbase\n&quot; :&lt;br/&gt;	    &quot;not ok: Disconnect from Essbase\n&quot;;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;This one’s pretty self-explanatory.  It calls the disconnect() function and prints the return value.&lt;br/&gt;&lt;br/&gt;In my next post, I’ll discuss a couple of subroutines to run Alter and Aggregate MaxL commands.</description>
    </item>
    <item>
      <title>Essbase_Perl.pm subroutines (handling errors)</title>
      <link>http://www.perly-gates.com/The_Perly-Gates/Essbase_%26_Perl/Entries/2008/8/26_Essbase_Perl.pm_subroutines_%28handling_errors%29.html</link>
      <guid isPermaLink="false">c91a4b66-2292-4c43-a7c5-1978a99607d6</guid>
      <pubDate>Tue, 26 Aug 2008 16:47:26 -0400</pubDate>
      <description>In the last post I discussed the exeMAXL subroutine of the &lt;a href=&quot;Entries/2008/8/26_Essbase_Perl.pm_subroutines_%2528handling_errors%2529_files/Essbase_Perl-2.pm&quot;&gt;Essbase_Perl.pm&lt;/a&gt;.  You’ll recall that this subroutine is used to run MaxL commands, return the resulting messages, and check for any errors.  But what happens if running the command does result in errors?  Well, that’s the topic of today’s post.&lt;br/&gt;&lt;br/&gt;If you remember from yesterday’s post, the exeMAXL subroutine had the following line of code after running the MaxL command:&lt;br/&gt;&lt;br/&gt;&amp;amp;errHandler($dbh, $cmd, @messages) if $result != 0;&lt;br/&gt;&lt;br/&gt;If the return code ($result) from the MaxL command is not equal to zero (zero meaning that no errors occurred), the errHandler subroutine is called from exeMAXL.  Here’s what it looks like:&lt;br/&gt;&lt;br/&gt;sub errHandler {&lt;br/&gt;        my ($dbh, $cmd, @errors) = @_;&lt;br/&gt;        my $ret = &amp;amp;sendMsg($err_to, $err_from, &quot;error occurred in $cmd&quot;, join(&quot;&quot;,@errors),&quot;&quot;);&lt;br/&gt;        print &quot;***********stopping load process due to following error in $cmd:\n@errors&quot;;&lt;br/&gt;        &amp;amp;Ess_disconnect($dbh) if $dbh != 1;&lt;br/&gt;        exit;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;In the first line, the database handle ($dbh) is passed in, along with the MaxL command and the messages (including the error message) resulting from the command’s execution.  The second line calls the sendMsg subroutine, which uses a Perl library (Mime::Lite) to send an email informing you of the error and including the command and error messages.  The next line prints the same information.  Next, we call a subroutine to disconnect from the Essbase server.  The final line exits the code, preventing any further MaxL commands from being executed.&lt;br/&gt;&lt;br/&gt;We’ve briefly encountered two new subroutines (sendMsg and Ess_disconnect).  In my next post I’ll discuss these in more detail.</description>
    </item>
    <item>
      <title>Essbase_Perl.pm subroutines (executing maxl commands)</title>
      <link>http://www.perly-gates.com/The_Perly-Gates/Essbase_%26_Perl/Entries/2008/8/25_Essbase_Perl.pm_subroutines_%28executing_maxl_commands%29.html</link>
      <guid isPermaLink="false">dfb61477-b476-4e06-b890-7e04b86e6c00</guid>
      <pubDate>Mon, 25 Aug 2008 20:14:01 -0400</pubDate>
      <description>When we left off yesterday I promised to discuss the &lt;a href=&quot;Entries/2008/8/25_Essbase_Perl.pm_subroutines_%2528executing_maxl_commands%2529_files/Essbase_Perl-2.pm&quot;&gt;Essbase_Perl.pm&lt;/a&gt; in more detail.  Let’s jump right in.&lt;br/&gt;&lt;br/&gt;The heart of this package is the exeMAXL subroutine.  As the name suggests, this sub executes a MaxL command.  Taking it line by line, the first line -- my ($dbh, $cmd) = @_; -- gets the arguments passed into the sub.  $dbh represents a database connection and is returned from the second sub below -- Ess_connect.  The second argument -- $cmd -- is the actual MaxL command to be executed.&lt;br/&gt;&lt;br/&gt;The second line, containing $dbh-&gt;do, actually runs the MaxL command, returning the exit code to $result.  If the command ran without errors, $result should be equal to zero.  The next line checks $result and prints the result.&lt;br/&gt;&lt;br/&gt;The fourth line, beginning with ‘my @messages’, returns the messages from the Essbase stack from running the command and stores them in the @messages array.&lt;br/&gt;&lt;br/&gt;The next few lines call an error handling routine (errHandler) if any errors occurred.  I’ll discuss this sub in detail tomorrow.&lt;br/&gt;&lt;br/&gt;The last line returns the result and the messages to the calling subroutine.&lt;br/&gt;&lt;br/&gt;sub exeMAXL {&lt;br/&gt;         my ($dbh, $cmd) = @_;&lt;br/&gt;         my $result = $dbh-&gt;do($cmd);&lt;br/&gt;&lt;br/&gt;         $result == 0 ? print &quot;ok: $cmd\n&quot; : print &quot;not ok: $cmd\n&quot;;&lt;br/&gt;&lt;br/&gt;         my @messages = &amp;amp;msgs($dbh);&lt;br/&gt;         $result = 0 if $messages[1] =~ /$non_error/;&lt;br/&gt;         &amp;amp;errHandler($dbh, $cmd, @messages) if $result != 0;&lt;br/&gt;         return ($result, @messages)&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;sub Ess_connect {&lt;br/&gt;	my ($user, $password) = @_;&lt;br/&gt;	my $dbh = Essbase-&gt;connect($user, $password);&lt;br/&gt;&lt;br/&gt;	# make sure the database connection succeeded&lt;br/&gt;	$dbh-&gt;{STATUS} == $Essbase::MAXL_STATUS{NOERR} ? return(0,$dbh) :&lt;br/&gt;	        return(1,$dbh);&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;So please come back tomorrow for further explanation of &lt;a href=&quot;Entries/2008/8/25_Essbase_Perl.pm_subroutines_%2528executing_maxl_commands%2529_files/Essbase_Perl-2.pm&quot;&gt;Essbase_Perl.pm&lt;/a&gt;, my package encapsulating and simplifying the functionality of the Essbase Perl module.</description>
    </item>
    <item>
      <title>Essbase load program unveiled</title>
      <link>http://www.perly-gates.com/The_Perly-Gates/Essbase_%26_Perl/Entries/2008/8/24_Essbase_load_program_unveiled.html</link>
      <guid isPermaLink="false">566a993f-2ad8-4be6-afd9-b4ed305a2dbe</guid>
      <pubDate>Sun, 24 Aug 2008 19:25:54 -0400</pubDate>
      <description>I wanted to share with everyone a Perl program that I wrote.  This program takes advantage of the power and flexibility provided by the Essbase Perl module (essbase.pm) included in every Essbase installation.  You can find it under the {arborpath}\perlmod directory.&lt;br/&gt;&lt;br/&gt;WIth the &lt;a href=&quot;Entries/2008/8/24_Essbase_load_program_unveiled_files/Essbase_Perl-2.pm&quot;&gt;Essbase_Perl.pm&lt;/a&gt; you can execute MaxL statements directly from Perl.  It then becomes possible to take advantage of the error handling and logic provided by Perl to create a very flexible program for loading data into Essbase databases.&lt;br/&gt;&lt;br/&gt;The &lt;a href=&quot;Entries/2008/8/24_Essbase_load_program_unveiled_files/Essbase_Perl-2.pm&quot;&gt;Essbase_Perl.pm&lt;/a&gt;, which I’ll explain in detail tomorrow, is a Perl package that I created as a wrapper for the Essbase Perl module.  Because it's not necessary to know the actual MaxL syntax involved, you can accomplish complex tasks by using simple Perl subroutine calls like the following:&lt;br/&gt;&lt;br/&gt;my ($return, @msgs) = Essbase_Perl::Ess_import($dbh, &quot;FISDPL&quot;, &quot;Main&quot;, &quot;D:/Hyperion/AnalyticServices/app/FISDPL_P/Main/xptcrpHIST01&quot;, &quot;Load_CY_ASO.xptcrpHIST01&quot;, &quot;xptcrp0c&quot;, &quot;data&quot;, 6, &quot;.flp&quot;);&lt;br/&gt;&lt;br/&gt;On the other hand, you can configure an XML file (please see &lt;a href=&quot;Entries/2008/8/24_Essbase_load_program_unveiled_files/config_load.xml&quot;&gt;config_load.xml&lt;/a&gt;l) with the commands, and the order in which you want to run them.  The above is represented in the XML configuration file by the following:&lt;br/&gt;&lt;br/&gt;&amp;lt;command num=&quot;1&quot; type=&quot;import&quot; action=&quot;data&quot; rules_file=&quot;xptcrp0c&quot; num_files=&quot;6&quot; file_ext=&quot;.flp&quot;&gt;&lt;br/&gt;          &amp;lt;data_file&gt;D:/Hyperion/AnalyticServices/app/FISDPL_P/Main/xptcrpHIST01&amp;lt;/data_file&gt;&lt;br/&gt;          &amp;lt;error_file&gt;Load_CY_ASO.xptcrpHIST01&amp;lt;/error_file&gt;&lt;br/&gt;&amp;lt;/command&gt;&lt;br/&gt;&lt;br/&gt;This replaces the following lengthy syntax:&lt;br/&gt;MAXL&gt; import database &quot;'FISDPL'&quot;.&quot;'Main'&quot; data&lt;br/&gt;   2&gt;    from local data_file      &quot;'D:\Hyperion\AnalyticServices/app/FISDPL_P/Main/xptcrpHIST01.1.flp'&quot;&lt;br/&gt;   3&gt;    using server rules_file   &quot;'xptcrp0c'&quot;&lt;br/&gt;   4&gt;    on error write to         &quot;'D:\Hyperion\AnalyticServices/client/FISDPL/Main/Load_Data_CY.X.xptcrpHIST01.1.err'&quot;;&lt;br/&gt;&lt;br/&gt;MAXL&gt; import database &quot;'FISDPL'&quot;.&quot;'Main'&quot; data&lt;br/&gt;   2&gt;    from local data_file      &quot;'D:\Hyperion\AnalyticServices/app/FISDPL_P/Main/xptcrpHIST01.2.flp'&quot;&lt;br/&gt;   3&gt;    using server rules_file   &quot;'xptcrp0c'&quot;&lt;br/&gt;   4&gt;    on error write to         &quot;'D:\Hyperion\AnalyticServices/client/FISDPL/Main/Load_Data_CY.X.xptcrpHIST01.2.err'&quot;;&lt;br/&gt;&lt;br/&gt;MAXL&gt; import database &quot;'FISDPL'&quot;.&quot;'Main'&quot; data&lt;br/&gt;   2&gt;    from local data_file      &quot;'D:\Hyperion\AnalyticServices/app/FISDPL_P/Main/xptcrpHIST01.3.flp'&quot;&lt;br/&gt;   3&gt;    using server rules_file   &quot;'xptcrp0c'&quot;&lt;br/&gt;   4&gt;    on error write to         &quot;'D:\Hyperion\AnalyticServices/client/FISDPL/Main/Load_Data_CY.X.xptcrpHIST01.3.err'&quot;;&lt;br/&gt;&lt;br/&gt;MAXL&gt; import database &quot;'FISDPL'&quot;.&quot;'Main'&quot; data&lt;br/&gt;   2&gt;    from local data_file      &quot;'D:\Hyperion\AnalyticServices/app/FISDPL_P/Main/xptcrpHIST01.4.flp'&quot;&lt;br/&gt;   3&gt;    using server rules_file   &quot;'xptcrp0c'&quot;&lt;br/&gt;   4&gt;    on error write to         &quot;'D:\Hyperion\AnalyticServices/client/FISDPL/Main/Load_Data_CY.X.xptcrpHIST01.4.err'&quot;;&lt;br/&gt;&lt;br/&gt;MAXL&gt; import database &quot;'FISDPL'&quot;.&quot;'Main'&quot; data&lt;br/&gt;   2&gt;    from local data_file      &quot;'D:\Hyperion\AnalyticServices/app/FISDPL_P/Main/xptcrpHIST01.5.flp'&quot;&lt;br/&gt;   3&gt;    using server rules_file   &quot;'xptcrp0c'&quot;&lt;br/&gt;   4&gt;    on error write to         &quot;'D:\Hyperion\AnalyticServices/client/FISDPL/Main/Load_Data_CY.X.xptcrpHIST01.5.err'&quot;;&lt;br/&gt;&lt;br/&gt;MAXL&gt; import database &quot;'FISDPL'&quot;.&quot;'Main'&quot; data&lt;br/&gt;   2&gt;    from local data_file      &quot;'D:\Hyperion\AnalyticServices/app/FISDPL_P/Main/xptcrpHIST01.6.flp'&quot;&lt;br/&gt;   3&gt;    using server rules_file   &quot;'xptcrp0c'&quot;&lt;br/&gt;   4&gt;    on error write to         &quot;'D:\Hyperion\AnalyticServices/client/FISDPL/Main/Load_Data_CY.X.xptcrpHIST01.6.err'&quot;;&lt;br/&gt;&lt;br/&gt;The Perl code will run the commands listed in the order specified in the &lt;a href=&quot;Entries/2008/8/24_Essbase_load_program_unveiled_files/config_load.xml&quot;&gt;config_load.xml&lt;/a&gt;, checking for errors after each command. It is configured to halt the load and send an email with details of the encountered error to an email address also indicated in the &lt;a href=&quot;Entries/2008/8/24_Essbase_load_program_unveiled_files/config_load.xml&quot;&gt;config_load.xml&lt;/a&gt; configuration file.  If no errors are encountered, the program will send an email notifying of its successful completion.  The body of the email notification is read from a text file in a specified location.&lt;br/&gt;&lt;br/&gt;&lt;a href=&quot;Entries/2008/8/24_Essbase_load_program_unveiled_files/Essbase_Perl-2.pm&quot;&gt;Essbase_Perl.pm&lt;/a&gt; is not limited to MaxL commands.  It can also execute .bat and .cmd files.&lt;br/&gt;&lt;br/&gt;As you can see, this program is highly configurable.  More details to come tomorrow.</description>
    </item>
  </channel>
</rss>
