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

<channel>
	<title>Komotini Blogs &#187; Programming and DBA</title>
	<link>http://www.komotiniblogs.gr/</link>
	<description>Komotini Blogs &#187; Programming and DBA</description>
	<generator>Gregarius 0.5.5</generator>
	<language>en</language>
	<item>
		<title>Programming and DBA: Chromium repository for Fedora</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2010/08/19/Chromium_repository_for_Fedora</link>
		<pubDate>Thu, 19 Aug 2010 10:54:00 -0400</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2010/08/19/Chromium_repository_for_Fedora</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
This is only a quick note for me and anyone else <i>still</i> searching for the new location of the chromium repo for Fedora. The new location is :
</p>
<p>
<a href="http://repos.fedorapeople.org/repos/spot/chromium/">
  <a href="http://repos.fedorapeople.org/repos/spot/chromium/">[repos.fedorapeople.org]</a> </a>
</p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-7275137581762166366?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: Hello T-SQL and ASP.NET</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2010/07/09/Hello_T-SQL_and_ASP.NET</link>
		<pubDate>Fri, 09 Jul 2010 11:39:00 -0400</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2010/07/09/Hello_T-SQL_and_ASP.NET</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
Half of me wishes things had gone the way I planned, so now we would be programming with CakePHP storing data in Oracle and calling remote enabled function modules in order to communicate with SAP. 
Then my other half says: "Ok, no more reading and mangling with ABAP spaghetti code written by somebody afraid to declare a single local variable and trying to figure out what all these magic tables with the enlightening four-letter names do!" Of course getting rid of ABAP is the bright side. The dark side said says "Hello from 1 Microsoft Way Redmond WA" 
</p>
After the company I work for was sold out right before Christmas, the new management decided that SAP was too expensive and too complicated so from now the entire group we will be using a Greek ERP made by Entersoft SA. The new ERP is an N-Tier system running under Windows written in .NET and uses Microsoft SQL Server as data store. So what is left for us now is to learn and program in .NET
</p>

<p>
Being the Linux junkie I am, this development in my developer status triggered various comments from friends and neighbours. The most interesting was this video trailer which much like Sgt. Pepper's Lonely Hearts Club Band is ... guaranteed to raise a smile.
</p>
<p>
So Java vs .NET; the choice is not always yours sο sit back and enjoy
<p> 

</p>
<p>
Stay tuned for more.
</p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-5061808296600622024?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: Flash player for 64 bit Linux</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2010/04/14/Flash_player_for_64_bit_Linux</link>
		<pubDate>Wed, 14 Apr 2010 10:11:00 -0400</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2010/04/14/Flash_player_for_64_bit_Linux</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
Thanks to 
 <a href="http://forums.fedoraforum.org/showthread.php?t=205642&amp;highlight=64bit+flash+player+repository">
    Leigh's
  </a> 
  repository for Fedora, I almost forgot where to find the latest 
  version of flash player.
</p>
<p>So, to save a little bit of googling ...</p>
<ul>
  <li>
    <a href="http://labs.adobe.com/technologies/flashplayer10/64bit.html">
      Flash Player 10 for 64-bit Linux page
    </a>
  </li>
  <li>
    <a href="http://labs.adobe.com/downloads/flashplayer10_64bit.html">
      Flash player direct download lpage
    </a>
  </li>
</ul><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-2542405450964139222?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: Linux: Mass rename of files</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2010/02/07/Linux:_Mass_rename_of_files</link>
		<pubDate>Sun, 07 Feb 2010 12:46:00 -0500</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2010/02/07/Linux:_Mass_rename_of_files</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
When people give me files, especially images, coming from windows machines I always have problems with capitalised extensions. JPEG format files for instance appear as <code>image.JPG</code> instead of <code>image.jpg</code>. Worst case is that in some collections some file extensions appear capitalised while others in lower case.
</p>
<p>
I have searched the web for some simple solution to this problem and ended up seeing <code>sed</code> commands and pipes that <a href="http://6v8.gamboni.org/Mass-renaming-with-linux-shell.html">UNIX gurus</a> are so fond off, 
</p>
<blockquote>
So, if you wanted to rename all the .php3  to .php, this would be the command:
<br>
<code>
ls -d *.php3 | sed 's/\(.*\).php3$/mv "&amp;" "\1.php"/' | sh
</code>
</blockquote>
<p>
As Fortune keeps reminding me, there is more than one way to skin a cat, so a more complete discussion on mass renaming with Linux can be found on Gareth Anderson's <a href="http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/index.html">GNU/Linux Command-Line Tools Summary
</a> book article directly accessible from <a href="http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/mass-rename.html">here</a>.
</p>
<p>
Anyway, after a little bit of googling, it turned out to my surprise that the simplest way to do this was inside my own Fedora distro. The magic command is rename and the man entry is small, simple and accurate :
</p>
<pre>
RENAME(1)                  Linux Programmer’s Manual                 RENAME(1)

NAME
       rename - Rename files

SYNOPSIS
       rename from to file...
       rename -V

DESCRIPTION
       rename will rename the specified files by replacing the first occurrence of from in their name by to.

       -V, --version
              Display version information and exit.

       For example, given the files
              foo1, ..., foo9, foo10, ..., foo278, the commands

              rename foo foo0 foo?
              rename foo foo0 foo??

       will turn them into foo001, ..., foo009, foo010, ..., foo278.

       And
              rename .htm .html *.htm

       will fix the extension of your html files.

SEE ALSO
       mmv(1), mv(1)

AVAILABILITY
       The   rename   command   is   part   of   the   util-linux-ng   package   and   is   available  from  ftp://ftp.ker-
       nel.org/pub/linux/utils/util-linux-ng/.

                                1 January 2000                       RENAME(1)

</pre>
<p>
The rename command is also available on all EL clones like (CentOS and Oracle EL).
</p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-2737526550533752095?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: CakePHP: Calling Oracle stored functions</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2010/01/20/CakePHP:_Calling_Oracle_stored_functions</link>
		<pubDate>Wed, 20 Jan 2010 15:45:00 -0500</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2010/01/20/CakePHP:_Calling_Oracle_stored_functions</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
Our testing with Cake is almost complete. We have been able to read and write data correctly in our non UTF-8 Oracle database, managed to communicate with SAP, played enough with AJAX, so our users will not complain when dealing with tree like data and even managed to get authenticated by our MS-Windows 2003 active directory servers. So the last question left was how does one call an Oracle PL/SQL stored procedure or function from CakePHP ?
</p>
<p>
A little bit of googling and a little bit of digging into the CakePHP code revealed the following: The most common approach to calling stored procedures and functions is to create a member function in your model class and set up the call from there. In the simple case of calling a stored procedure with IN parameters only, the Model's <code>query()</code> method can be used to perform the actual call via the <code>CALL PROC_NAME( ... )</code> SQL statement. The usual approach is to create a model method like this :
</p>
<pre>
class MyModel extends AppModel {
    var $name = "MyModel";

    ...
    function callStoredProc( $param1, $param2)
    {
        $this-&gt;query("CALL my_stored_proc( $param1, $param2");
    }
    ...
}

</pre>
<p>
If however you need to get data in and out of Oracle then you have to get your hands dirty and set up the call using low level oci_* functions. A simple example will clarify everything.
</p>
<p>
Let us suppose that you library users require that you display the average number of pages of the books stored in your library. A simple PL/SQL function to return this would probably be something like this:
/p&gt;
<pre>
CREATE OR REPLACE FUNCTION average_book_pages RETURN NUMBER
IS
   page_avg NUMBER;   
BEGIN
   SELECT avg( num_pages) 
      INTO page_avg
      FROM books;
   RETURN page_avg;   
END AVERAGE_BOOK_PAGES;
</pre>
<p>
The next thing to do would be to create a <code>getAvergaeBookPages()</code> function in our <code>Book</code> model class :
<pre>
&lt;?php
class Book extends AppModel {
    var $name = 'Book';
    var $belongsTo = ...
    var $validate = array( ...

    function getAverageBookPages()
    {
        // every model has a datasource
        $dataSource = $this-&gt;getDataSource();
        // and every datasource has a  database connection handle
        $connection = $dataSource-&gt;connection;
        if (!$connection)
            return -1;

        // from now you need this Oracle specific approach 
        $statement = oci_parse( $connection,
                "begin :ret := AVERAGE_BOOK_PAGES(); end;");
        oci_bind_by_name($statement, ':ret', $r, 100);
        oci_execute($statement);
        return $r;
    }
}
?&gt;
</pre>
<p>
The last parameter of <code>oci_bind_by_name</code> is the number of bytes to allocate for returning the string representation of the bind variable. Just make sure that you allocate enough memory for that. My test data yield an average of 762,666666666666666666666666666666666667 pages per book (Thank you Mr. Minasi) and so oci_execute kept giving me ORA-06502: PL/SQL: numeric or value error: character string buffer too small until I raised the value to 100.
</p>
<p>
So that does it. Now calling this from you controller code is as easy as :
</p>
<pre>
&lt;?php
class BooksController extends AppController {
    var $name = 'Books';

    ...

    function index()
    {
        $this-&gt;Book-&gt;recursive = 0;
        $this-&gt;set('books', $this-&gt;paginate());
        $this-&gt;set('averagePages', $this-&gt;Book-&gt;getAverageBookPages());
    }

    ...
}
</pre><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-2311741307332361715?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: CakePHP: The dependent listboxes problem</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2010/01/07/CakePHP:_The_dependent_listboxes_problem</link>
		<pubDate>Thu, 07 Jan 2010 12:30:00 -0500</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2010/01/07/CakePHP:_The_dependent_listboxes_problem</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
When creating dynamic web-sites, sooner or later you are going to face the problem of providing dependent list boxes. Imagine the case where one wishes to select a city from a list grouped by region, or a user from a group, an invoice from an order etc. Grouping things into categories is very common in real life and as far as I am concerned, it is almost always a must for your application to be able to utilize such groupings.
</p>
<p>
In CakePHP -- as far as I know -- there are two ways you can help your users pick up a value from a list of grouped items. One is to create a select box whose items are organized in selection groups sorted in some logical way. the other way in to use dependent AJAX triggered combo or list boxes where selection on the first will filter the items displayed on the second.
</p>
<p>
In this posting I will provide code that handles both cases.
</p>
The sample data
<p>
As an exercise for learning Cake, I developed a small application that manages the IT department books. Each <code>Book</code> belongs to a <code>BookCategory</code> and each <code>BookCategory</code> belongs to a <code>BookCategoryGroup</code>. Reversely, each <code>BookCategoryGroup</code> has many <code>BookCategory</code> and each <code>BookCategory</code> has many <code>Book</code>. The corresponding tables have foreign keys adhering to the CakePHP conventions, so I am not going to waste any more time explaining the data structure.  
</p>
<p>
The goal here is to help our users, when adding or editing book records, to find the right category for each book given the organization of book categories in book category groups. Like I said in the introduction there are two ways we can accomplish this
</p>
One combo box organized in selection groups
<p>
The way is very easy to implement and may become particularly handy whenever the total number of list items is relatively small. Cake's <code>Form::imput</code> method will create option groups if the array containing the options for a select box is organized into sub arrays so if 
we add the following function in our <code>BooksController</code> ....
</p>
<pre>
    private function prepareCategoriesCombo()
    {
        // gain access to the BookCategoryGroups model class
        $this-&gt;loadModel('BookCategoryGroup');
        // prepare a list of all book category groups
        $this-&gt;BookCategoryGroup-&gt;recursive = 0;
        $bookCategoryGroups = $this-&gt;BookCategoryGroup-&gt;find(
                                'all',
                                array(
                                    'conditions' =&gt; array(),
                                    'order' =&gt; array('BookCategoryGroup.name')
                                )
                            );

        // create an empty array to hold the combo box options
        $bookCategories = array();
        foreach( $bookCategoryGroups as $bookCategoryGroup) {
            $groupId = $bookCategoryGroup['BookCategoryGroup']['id'];
            $groupName = $bookCategoryGroup['BookCategoryGroup']['name'];
            // create a sub array for each group category
            $bookCategories[] = $groupName;
            // fill the array with the categories corresponding to the group
            $bookCategories[$groupName] = $this-&gt;Book-&gt;BookCategory-&gt;find(
                                'list',
                                array (
                                    'conditions' =&gt; array(
                                        'BookCategory.book_category_group_id' =&gt; $groupId
                                        ),
                                    'order' =&gt; array(
                                        'BookCategory.name'
                                        )
                                )
                                    );
        }
        return $bookCategories;
    }
</pre>
<p>
Supposing that you have baked your original controller and view code with the cake script, your <code>add()</code> or <code>edit()</code> controller actions need to have the following in order to use the option grouped combo:
</p>
<pre>   ...
   $bookCategories = $this-&gt;prepareCategoriesCombo();
   ...
</pre>
<p>
while the view template will require no change at all (i.e. a simple 
<code>echo $form-&gt;input('book_category_id');</code> will suffice). As I said earlier on, this method is simple enough and unless you intent to let your users pick a US zip code organized by state, this may be the preferred solution for many cases. If however you have lots of data and an
untamable desire for ajax, read on; fear not however CakePHP's approach to AJAX makes this look also like a piece of cake.
</p>
The AJAX way: Two combos with one auto filtering the other
<p>
The basic idea behind AJAX is the following: You start by defining an area in you web page identifiable via the the HTML <code>id</code> attribute. Then when the user clicks on a button or changes the value of some control (edit, list or combo), you make an asynchronous call to the web server -- that is without having to reload the page -- and the server returns HTML code that is ready to be placed inside that area. The actual way you implement this depends on the libraries and the AJAX framework you use. Cake does that using the <a href="http://www.prototypejs.org/">prototype</a> and the <a href="http://script.aculo.us/">Scriptaculus</a> frameworks.
</p>
<p>
So to get things started, download prototype and scriptaculus and place the following files in your <code>APP/webroot/js</code> folder:
</p>
<pre>
builder.js   dragdrop.js  prototype.js      slider.js  unittest.js
controls.js  effects.js   scriptaculous.js  sound.js
</pre>
Having done that, modify you application layout in order to include them. Open <code>APP/view/layouts/default.ctp</code> and change the HTML head part so it looks like this :
<br />
<pre>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
  &lt;head&gt;
    &lt;meta <a href="http-equiv="Content-Type"">[http-equiv="Content-Type"]</a> content="text/html; charset=UTF-8"/&gt;
    &lt;title&gt;
      &lt;?php echo $title_for_layout; ?&gt;
    &lt;/title&gt;
    &lt;?php echo $html-&gt;css('it-library'); ?&gt;
    &lt;meta name="Generator" content="Quanta Plus" /&gt;
    &lt;meta name="Author" content="Thanassis Bakalidis" /&gt;
    &lt;?php if (isset($javascript)) : ?&gt;
      &lt;?php echo $javascript-&gt;link('prototype.js'); ?&gt;
      &lt;?php echo $javascript-&gt;link('scriptaculous.js'); ?&gt;;
    &lt;?php endif; ?&gt;
    &lt;?php echo $scripts_for_layout; ?&gt;
  &lt;/head&gt;
</pre>
<p>
The next thing to do is to modify our controller in order to provide Javascript and AJAX support: Our books controller now looks like the following:
</p>
<pre>
class BooksController extends AppController {

    var $name = 'Books';
    var $helpers = array('Html', 'Form', 'Javascript', 'Ajax');
    var $components = array('RequestHandler');

    ...
}
</pre>
<p>
Next go to your view template -- may that be the add or edit.ctp -- and change the initial <code>echo $form-&gt;input('Book.book_category_id');</code> line in order to look like the following:
<pre>
        // here are the two list boxes displaying groups and categories
        // aim is to create an auto-filter effect with AJAX
        echo $form-&gt;label( 'BookCategory.book_category_group_id',
                            'Category Group');
        echo $form-&gt;select('BookCategory.book_category_group_id',
                            $bookCategoryGroups,
                            $bookCategoryGroupId,
                            array(
                                'id' =&gt; 'bookCategoryGroups'
                            ),
                            FALSE);
        echo $form-&gt;input('Book.book_category_id', array('id' =&gt; 'bookCategories' ));

        // each time the bookCategoryGroups element changes we are to
        // asynchronously call the updateSelect action of the current 
        // controller and insert whatever the action produces inside the 
        // html DOM element identified by bookCategories
        $ajaxOptions = array('url' =&gt; 'updateSelect','update' =&gt; 'bookCategories');
        echo $ajax-&gt;observeField('bookCategoryGroups',$ajaxOptions);
</pre>
<p>
I believe that the code is self explanatory. Now let us add the <code>updateSelect</code> method of the <code>BooksController</code> class
</p>
<pre>
    function updateSelect()
    {
        $groupId = $this-&gt;data['BookCategory']['book_category_group_id'];
        if (!empty( $groupId )) {
            $options = $this-&gt;getBookCategoriesForGroup( $groupId);
            // these are the combo box options to be used in the view file
            $this-&gt;set('options',$options);
        }
    }
</pre>
<p>
There is one thing to mention here: the AJAX code produced by <code>observeField()</code> serializes the entire field that is supposed to observe, so this will be available in the controller action as <code>$this-&gt;data['Model']['field']</code>.
</p>
<p>
Next we need to create the actual view code. Create a file named <code>update_select.ctp</code> inside your <code>APP/views/books</code> directory and place the following code inside:
</p>
<pre>
&lt;?php
    // create  tags coming from a $options variable
    // This is to be used by AJAX in order to fill the contents of a combo
    // box
    if(!empty($options)) {
        foreach($options as $key =&gt; $value) {
            echo "$value";
        }
    }
?&gt;
</pre>
<p>
Now we have everything in place. The only thing left to do is to initialize the two combo boxes so that they contain the correct data, i.e. all the group categories for the top combo and the categories for the selected records category group on the second, during initial page load. To achieve this I have created two additional functions in the <code>BooksController</code> class:
</p>
<pre>
    private function getBookCategoriesGroups()
    {
        $this-&gt;loadModel('BookCategoryGroup');
        $this-&gt;BookCategoryGroup-&gt;recursive = 0;
        return $this-&gt;BookCategoryGroup-&gt;find('list',
                                                array(
                                                    'conditions' =&gt; array(),
                                                    'order' =&gt; array(
                                                        'BookCategoryGroup.name'
                                                        )
                                                )
                                            );
    }

    private function getBookCategoriesForGroup( $groupId)
    {
        return $this-&gt;Book-&gt;BookCategory-&gt;find('list',
                                array(
                                    'conditions' =&gt; array (
                                        'book_category_group_id' =&gt; $groupId
                                        ),
                                    'order' =&gt; array(
                                            'BookCategory.name'
                                        )
                                )
                            );
    }
</pre>
<p>
Now my controller's edit action -- which as I mentioned earlier, was baked by cake -- looks like the following. 
</p>
<pre>
    function edit($id = null)
    {
        if (!$id &amp;&amp; empty($this-&gt;data)) {
            $this-&gt;Session-&gt;setFlash(__('Invalid Book', true));
            $this-&gt;redirect(array('action'=&gt;'index'));
        }
        if (!empty($this-&gt;data)) {
            if ($this-&gt;Book-&gt;save($this-&gt;data)) {
                $this-&gt;Session-&gt;setFlash(__('The Book has been saved', true));
                $this-&gt;redirect(array('action'=&gt;'index'));
            } else {
                $this-&gt;Session-&gt;setFlash(__('The Book could not be saved. Please, try again.', true));
            }
        }

        if (empty($this-&gt;data)) {
            $this-&gt;data = $this-&gt;Book-&gt;read(null, $id);
        }

        // set up additional book record parameters
        $sites = $this-&gt;Book-&gt;Site-&gt;find('list');
        $bookTypes = $this-&gt;Book-&gt;BookType-&gt;find('list');
        $languages = $this-&gt;Book-&gt;Language-&gt;find('list');

        // setup the two AJAX operated combo boxes
        $bookCategoryGroups = $this-&gt;getBookCategoriesGroups();                
        $bookCategoryGroupId = $this-&gt;data['BookCategory']['book_category_group_id'];
        $bookCategories = $this-&gt;getBookCategoriesForGroup( $bookCategoryGroupId);

        $ratings = $this-&gt;Book-&gt;Rating-&gt;find('list');
        $publishers = $this-&gt;Book-&gt;Publisher-&gt;find('list');

        $this-&gt;set( compact( 'sites','bookTypes','languages',
                             'bookCategories', 'bookCategoryGroups', 'bookCategoryGroupId',
                             'ratings','publishers'));
    }
</pre>
<p>
Needless to say that when adding a record, the initial <code>$bookCategoryGroupId</code> can be set to an initial value say 1 and then let your uses change to whatever seems appropriate.
</p>
<p>
I have tested this with CakePHP 1.2.5 on both Firefox (versions 3 and 3.5) and IE (version 8).
</p>
<p>
As a last statement, I would like to point out that I am by no means an expert on AJAX or CakePHP. I got my info from an earlier posting by <a href="http://www.devmoz.com/blog/2007/04/04/cakephp-update-a-select-box-using-ajax/">DEVMOZ</a> and the CakePHP <a href="http://api.cakephp.org/class/ajax-helper">AJAXHelper</a> class info page. I have put this down as a working reference to a real problem, that anybody can copy -- hopefully -- easy to modify code.
</p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-4240902833896380520?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: CakePHP and Oracle on CentOS. My own how to guide</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/12/16/CakePHP_and_Oracle_on_CentOS._My_own_how_to_guide</link>
		<pubDate>Wed, 16 Dec 2009 12:30:00 -0500</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/12/16/CakePHP_and_Oracle_on_CentOS._My_own_how_to_guide</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
During the last couple of days I formated and set up from scratch my CakePHP development server, using CentOS, php 5.3 from Remi and the Oracle 11gR2 clients. The log of my actions in PDF can be downloaded from <a href="https://docs.google.com/leaf?id=0B6KLBoL1nvwLZmYyMWMyZmMtMTk5MS00Y2E4LTg2ZjUtOWUwNWI4NWM1ZmI0&amp;hl=en_GB">here</a>.
</p>
<p>
During the following days I will setup one more server -- supposed to be the one that we will use productively -- following these same instructions. If I find any mistakes I will correct them and post back the orginal file here.
</p>
Update history
<ul>
  <li>
    Dec-28-2009: Added information about setting up  
    and running the cake scripts from the command line.
  </li>
  <li>
    Jan-21-2010: Verified contents on a new installation
    and added reminder for configuring the firewall.
  </li>
</ul><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-6691417479418274705?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: CakePHP: A behavior for acessing non UTF Oracle databases</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/12/15/CakePHP:_A_behavior_for_acessing_non_UTF_Oracle_databases</link>
		<pubDate>Tue, 15 Dec 2009 11:46:00 -0500</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/12/15/CakePHP:_A_behavior_for_acessing_non_UTF_Oracle_databases</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
The origins of our company's Oracle database date back at the beginning of the decade. At that time we had Oracle version 9i running on SuSE Linux 8.2 and the expected thing to do back then was to create a database using the EL8ISO8859P7 character set. After eight years we are still using Oracle. Now the database is 11g and the database server is OEL 5.4. Basic data structures however, are still the same as they were back in 2002.
</p>
<p>
During the evaluation of CakePHP as our next development environment we very soon run into the problem of trying to insert and retrieve Unicode data from a non-unicode database. Since the <code>encoding</code> key of <code>$defualt</code> array member of the <code>DATABASE_CONFIG</code> class (stored in <code>app/config/database.php</code> file) has no effect when connecting to Oracle databases, we ended up creating an additional translation layer, that would convert data to and from Unicode when reading from and writing to Oracle. 
</p>
<p>
CakePHP's way of doing this kind of staff is to create <a href="http://book.cakephp.org/view/88/Behaviors">behaviors</a>. Ours is called <code>CharsetConverter</code>, so by CakePHP's standards it is  implemented in a class named <code>CharsetConverterBehavior</code> that is stored in a file named <code>charset_converter.php</code> which is located in the <code>APP/models/behaviors</code> directory. 
</p>
<p>
The approach here uses the <code>mb_convert_encoding</code> function provided with the php-mbstring package. The code implementation is the following
</p>
<pre>
&amp;lt?php
/**
 * A simple behavior that allows cake PHP to use single byte Oracle
 * and possibly other vendor -- databases
 * Tested with Oracle 11gR1
 *
 * @version 0.1
 * @author Thanassis Bakalidis
 */
class CharsetConverterBehavior extends ModelBehavior {
    // we have an Oracle database that dates back to 2002 so
    const DEFAULT_DB_LOCALE = 'ISO-8859-7';
    const DEFAULT_PAGE_LOCALE = 'UTF-8';

    const READING_FROM_DB = TRUE;
    const WRITING_TO_DB = FALSE;

    var $databaseLocale;
    var $webpageLocale;
    var $Model;

    function setup(&amp;$model, $settings=array())
    {
        $this-&gt;Model = $model;

        $this-&gt;databaseLocale = isset($settings['databaseLocale']) ?
                                    $settings['databaseLocale'] :
                                    self::DEFAULT_DB_LOCALE;
        $this-&gt;webpageLocale = isset($settings['webpageLocale']) ?
                                    $settings['webpageLocale'] :
                                    self::DEFAULT_PAGE_LOCALE;
    }

    /**
     * Change the query where clause to the datbase native character set.
     */
    function beforeFind( &amp;$queryData, $queryParams)
    {
        if (!isset( $queryParams['conditions']))
            return $queryParams;

        $queryParams['conditions'] = $this-&gt;recodeRecordArray(
                                                        $queryParams['conditions'],
                                                        self::WRITING_TO_DB);
        return $queryParams;
    }

    /**
     * Convert fetched data from single byte to utf-8
     */
    function afterFind(&amp;$model, $results, $primary)
    {
        return $this-&gt;recodeRecordArray($results, self::READING_FROM_DB);
    }

    /**
     * Convert data to be saved into the database speciffic locale
     */
    function beforeSave()
    {
        $this-&gt;Model-&gt;data = $this-&gt;recodeRecordArray( $this-&gt;Model-&gt;data,
                                                       self::WRITING_TO_DB);
        return true;
    }

    /**
     * Recursively traverse and convert the encoding of the array passed
     * as parameter.
     */
    function recodeRecordArray(&amp;$recordArray, $loading = TRUE)
    {
        foreach( $recordArray as $key =&gt; $value)
            if (is_array($value))
                $recordArray[$key] = $this-&gt;recodeRecordArray($value, $loading);
            else {
                if (is_numeric($value))
                    continue;
                $recordArray[$key] = $loading ?
                                    mb_convert_encoding(
                                                $value,
                                                $this-&gt;webpageLocale,
                                                $this-&gt;databaseLocale)
                                    :
                                    mb_convert_encoding(
                                                $value,
                                                $this-&gt;databaseLocale,
                                                $this-&gt;webpageLocale);
            }
        return $recordArray;
    }
}
?&gt;

</pre>
<p>
Once we have this in place, using the new behavior in one of our models is as simple as setting the correct value of the <code>$actAs</code> variable. Here is a simple example of a model using the Character set convention and validation.
</p>
<pre>
&lt;?php
    class Task extends AppModel {
        var $name = 'Task';
        var $actsAs = array(
                    'CharsetConverter' =&gt; array(
                                            'databaseLocale' =&gt; 'ISO-8859-7',
                                            'webpageLocale' =&gt; 'UTF-8'
                                        )
                    );
        var $validate = array(
                    'title' =&gt; array(
                                'rule' =&gt; 'notEmpty',
                                'message' =&gt; 'Task title cannot be left blank'
                    )
                );
    }
?&gt;
</pre>
<p>
Almost all applications contain more than one model. Perhaps the best place to put the <code>$actAs</code> definition would be the <code>AppModel</code> class defined in the file <code>app_model.php</code> in the root of your app directory 
<br><br>
I also understand that writing a behavior to accomplish the job of the database driver is not the best solution. Since I have nothing better for the moment, I guess I will have to start every new CakePHP project by first changing my <code>app_model.php</code> file.
</p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-1593131721631548361?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: How to set up the SAPRFC extension for PHP on CentOS 5</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/12/01/How_to_set_up_the_SAPRFC_extension_for_PHP_on_CentOS_5</link>
		<pubDate>Tue, 01 Dec 2009 12:47:00 -0500</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/12/01/How_to_set_up_the_SAPRFC_extension_for_PHP_on_CentOS_5</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	SAPRFC
<p>
<a href="http://saprfc.sourceforge.net/">SAPRFC</a> is an extension module for PHP 4 and 5, that makes it possible to call ABAP function modules running on a SAP R/3 system from PHP scripts.
</p>
<p>
I always wanted to test how SAP's remote function calls work together with PHP and since I am already evaluating <a href="http://www.cakephp.org">CakePHP</a> as our next development platform, I decided that the occasion was right to give it a try.
</p>
<p>
Next thing I did was to get my hands on <a href="http://www.amazon.com/SAP-Developers-Guide-PHP/dp/1592290663/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1259665626&amp;sr=8-1">The SAP Developer's Guide to PHP</a> book by Craig S. Cmehil, which is an $85 cost and 98 page long  (indexes included) tutorial on how to set up and use SAPRFC for PHP. Unfortunately the second chapter that discusses setting up your development system focuses mainly on Windows, so this post will contain the steps I took to set up SAPRFC for PHP on my x86_64 CentOS 5.4 server.
</p>

Package Requirements and Downloads
<p>To get the latest PHP packages for Enterprise Linux I have used Remi's repository.
</p>
<pre>
# wget <a href="http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-3.noarch.rpm">[download.fedora.redhat.com]</a> # wget <a href="http://rpms.famillecollet.com/enterprise/remi-release-5.rpm">[rpms.famillecollet.com]</a> # rpm -Uvh remi-release-5*.rpm epel-release-5*.rpm
</pre>
<p>
Remi's packages depend on the EPEL repository, so I am posting the installation procedure for EPEL as well. (if you haven't installed
it yet, now will be a good time to do so.)
</p>
<p>
In addition to any other PHP packages that your application requires, in order for the SAPRFC to compile correctly, you will also require the <code>php-devel</code> package.
</p>
<p>
Next thing is the SAPRFC package itself. The method to install it will be to build the saprfc extension as a dynamic module without rebuilding PHP. (Remi has already done that for us.) The package itself can be downloaded from <a href="http://saprfc.sourceforge.net/">here</a>.
</p>
<p>
Continue by installing SAP's Non Unicode RFC SDK version 6.20 or 6.40. This must be downloaded directly from the <a href="http://service.sap.com/support">SAP Service Support Portal</a>. You will need a customer SAP support ID
</p>
<p>
Be advised however, that SAP has implemented some form of a DNS transparent cluster for their WEB service, so each time you log in there,  you end up accessing a server with a different DNS name (something like <a href="https://websmp104.sap-ag.de/support).">[https:]</a> That means that your browser will not be able to store your credentials because every time you attempt to connect to <a href="https://service.sap.com/support,">[https:]</a> the DNS name changes so it pops up a dialog asking for login data again and again... Perhaps this is SAP's way of implementing the ultimate security system but, as far as I can say it is very annoying.
</p>
<p>
Anyway, once you are there select "Download" from the top menu. Next click "Search on all categories" from the left menu and enter <code>RFC SDK</code> on the search box that appears. You will be given the chance to select SAP RFC SDK 6.40 from the results page. Be careful not to choose the UNICODE version. Select Linux on x86_64 64bit from the list of architectures and you will end up with an SAR file in your download basket. Now you can download it 
</p>
<p>
There is one more problem though. The file you download is of type SAR. meaning SAP Archive. In order to unpack it you will need SAPCAR, SAP's unpacking program. You download this the same way you downloaded RFCSDK -- just type SAPCAR on the search box. Only thing is that the Linux x86_64 version does not run on CentOS. You will need to download a Windows version, unpack the archive on a Windows machine and then upload it again on you Linux system. At least that is what I had to do. (From what I was able to understand SAP's SAPCAR for Linux is compiled to run under SuSE, so if you have satch a machine, you can try unpacking the archive over there...)
</p>
Installation
<p>
So now let's assume that you have placed SAP's RFC SDK under <code>/opt/SAP/rfcsdk</code> and SAPRFC extention module for PHP under <code>/usr/src/saprfc-1.4.1/</code>. Type the following commands on your shell prompt 
or add them at the end of your startup file. (I put them in <code>/etc/profile</code>.)
<pre>
# SAP RFC SDK
export SAPRFC_DIR=/opt/SAP/rfcsdk/
export PATH=$SAPRFC_DIR/bin:$PATH
</pre>
<p>
If necessary, log out and back in again. Now move to the SAPRFC extension for PHP directory and issue the <code>phpize</code> command. This will create the <code>configure</code> script that needs to be run next. After configure completes, run <code>make</code> and <code>make install</code> (as root) to finish installation. When everything finishes the file <code>saprfc.so</code> will be placed in your <code>/usr/lib64/php/modules</code> folder. 
Open you <code>php.ini</code> file located in <code>/etc</code> and add a line line 
</p>
<pre>
extension=saprfc.so
</pre>
<p>
in the Dynamic Extensions section, save it, restart http server and you are ready to go.
<pre>
[root@barbara ~]# service <a href="httpd">[httpd]</a> restart
Stopping <a href="httpd:">[httpd:]</a>                                            [  OK  ]
Starting <a href="httpd:">[httpd:]</a>                                            [  OK  ]
</pre>
Verification and testing
<p>
The very first check will be as simple as looking at the saprfc section of your <code>phpinfo()</code> page. You should be seeing something like :
</p>
<a href="http://2.bp.blogspot.com/_CFT56hwlD5g/SxjiYmFVRPI/AAAAAAAAAOo/e7ac7D0eX9Y/s1600-h/Screenshot.png"><img src="http://2.bp.blogspot.com/_CFT56hwlD5g/SxjiYmFVRPI/AAAAAAAAAOo/e7ac7D0eX9Y/s400/Screenshot.png" /></a>
<p>
The next thing will be to write an actual program that does something more practical like connecting to an SAP R/3 system and fetching back some useful data. Since this already a rather lengthy post, I will prepare and provide a test program some time later.
</p>
<p>
One last comment: It took me a while to figure that out. All examples that come along with the SAPRFC module for PHP, as well as the examples on the "SAP Developer's Guide to PHP" book, use <code>&lt;?</code> instead of <code>&lt;?php</code> to introduce php code. This is going to give you a lot of trouble when attempting to use these files with php 5.3.1 so before trying anything else, go to the files in the installation directory -- especially <code>saprfc.php</code> that you will always include -- and perform the necessary changes.
</p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-4090332114206230218?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: Enterprise class hardware for Enterprise class software</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/11/27/Enterprise_class_hardware_for_Enterprise_class_software</link>
		<pubDate>Fri, 27 Nov 2009 16:30:00 -0500</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/11/27/Enterprise_class_hardware_for_Enterprise_class_software</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
We wanted to set up a portable LAMP server for a home project we are playing with and there it is : 
</p>
<p>
<a href="http://3.bp.blogspot.com/_CFT56hwlD5g/Sw_iowEagfI/AAAAAAAAAOY/aOOOZpEEqpc/s1600/trimmed.jpg"><img src="http://3.bp.blogspot.com/_CFT56hwlD5g/Sw_iowEagfI/AAAAAAAAAOY/aOOOZpEEqpc/s320/trimmed.jpg" /></a>
Since the little monster uses two SD cards as hard drives, it takes around four minutes to boot, but once it does boot, then its 900MHz Celeron CPU with its 1GB of RAM can stand up against a multi-threaded Java program gathering information from the local Ethernet and a complete Apache, PHP and MySQL server accessed for reporting.
</p>
<p>
Only thing is that the book is almost three times thicker than the machine.
</p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-8181565457061297190?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: SAP: All the little text tables</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/11/26/SAP:_All_the_little_text_tables</link>
		<pubDate>Thu, 26 Nov 2009 10:27:00 -0500</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/11/26/SAP:_All_the_little_text_tables</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
Even after 5 years of tampering with ABAP, I still have problems getting used to the way SAP name their production tables. All those four letter German abbreviated names are explanatory enough to scare away any newcomer. Even the English descriptive texts that SAP provides along with each object are so Spartan, that I very seldom can make any good use out of them. 
</p>
<p>
Luckily enough, I have just the right person available who seems to know all the four -- or five -- letter permutations that yield SAP table and field identifiers. (Thanks again Marilena), so today I am going to steal a few of her knowledge and give us code fragments that show how to get descriptive texts for various material and production related key's like material names, groups, blocking statuses, MRP controllers, etc.
</p>
<p>
We will start with the names of storage locations. The field and the data type for those are named <code>lgode</code>. The table that stores related info is <code>t001l</code>.
</p>
<pre>
   DATA :
     storage_location TYPE lgort_d, 
     storage_location_name TYPE lgobe.

    " storage_location = '...'.
    SELECT SINGLE lgobe
      INTO storage_location_name
      FROM t001l
      WHERE lgort = storage_location.
</pre>
<p>
The next one is easy. Even I know by heart how to get the material description given the material number, but I will put it down anyway. The thing to mention however, is that most SAP text tables are language dependent, so to get the text for the key, you also need to specify the language
</p>
<pre>
    DATA :
      material TYPE matnr,
      material_descr TYPE maktx.

    " material = '...'.
    SELECT SINGLE maktx
      INTO material_descr
      FROM makt
      WHERE matnr = material
        AND spras = sy-langu.
</pre>
<p>
Material types are stored in table <code>t134t</code> which is also language dependent.
</p>
<pre>
    DATA :
      material_type TYPE mtart,
      material_type_descr TYPE mtbez.

    " material_type = '...'.
    SELECT SINGLE mtbez
      INTO material_type_descr
      FROM t134t
      WHERE mtart = material_type
        AND spras = sy-langu.
</pre>
<p>
Our next table is <code>t141t</code>, that stores the various texts for the material blocking statuses.
</p>
<pre>
    DATA :
      mat_blocking_status TYPE mstae,
      mat_blocking_status_descr TYPE mstb.

 " Material blocking status descriptions
    SELECT SINGLE mtstb
      INTO mat_blocking_status_descr
      FROM t141t
      WHERE mmsta = mat_blocking_status
        AND spras = sy-langu.
</pre>
<p>
We wil now move to the inspiringly named <code>t023t</code> table, that provides access to the short and long names of material groups. 
</p>
<pre>
    DATA :
      material_group TYPE matkl,
      mat_group_short_descr type wgbez,
      mat_group_long_descr TYPE wgbez60.
    
    " material_group = "...".
    SELECT SINGLE wgbez wgbez60
      INTO (mat_group_short_descr, mat_group_long_descr)
      FROM t023t
      WHERE matkl = material_group
        AND spras = sy-langu.
</pre>
<p>
Product hierarchy descriptions are found in in  <code>t179t</code>.
</p>
<pre>
    DATA :
      mat_hierarchy TYPE prodh_d,
      mat_hierarchy_descr TYPE vtext.

    " mat_hierarchy = '...'.
    SELECT SINGLE vtext
      INTO mat_hierarchy_descr
      FROM t179t
      WHERE prodh = mat_hierarchy
        AND spras = sy-langu.
</pre>
<p>
Table <code>t438t</code> stores MRP type descriptions.
</p>
<pre>
    DATA :
      mrp_type TYPE dismm,
      mrp_type_descr TYPE disbez.

    SELECT SINGLE dibez
      INTO mrp_type_descr
      FROM t438t
      WHERE dismm = mrp_type
        AND spras = sy-langu.
</pre>
<p>
Last table for today's post will be <code>t024d</code>. this one contains MRP Controller descriptions and is not language but plant organized.
</p>
<pre>
    DATA :
      plant TYPE werks_d,
      mrp_controller type idspo,
      mrp_controller_descr TYPE disnam.

    SELECT SINGLE dsnam
      FROM t024d
      INTO mrp_controller_descr
      WHERE dispo = mrp_controller
        AND werks = plant.
</pre>
<p>
... and that is enough for one day.
</p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-4024212604676250136?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: The CakePHP manual in PDF</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/11/12/The_CakePHP_manual_in_PDF</link>
		<pubDate>Thu, 12 Nov 2009 10:40:00 -0500</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/11/12/The_CakePHP_manual_in_PDF</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
if anybody wants a PDF version of the entire CakePHP manual as it appears in <a>http://book.cakephp.org/</a>, the book is available from
<a href="http://docs.google.com/fileview?id=0B6KLBoL1nvwLMmRmMjVmZTYtZTVhMC00Y2RlLTlmNDItYzQ4NGI2Mjg3N2U4&amp;hl=en_GB">here</a>.
</p>
<p>
I created this document by copying and pasting text from the book website into an OpenOffice text document, because I wanted to have something to print and browse like a normal book. I have also added a few Oracle specific instructions. It is therefore possible, that some things may have slipped me. I will try and change this document every time I find an error or add a correction. Please feel free to post any mistakes you may find.
</p>
<p>
Last uploading: January 5-2010
</p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-2538694828731126543?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: How to split a music file givena .cue file.</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/10/31/How_to_split_a_music_file_givena_.cue_file.</link>
		<pubDate>Sat, 31 Oct 2009 21:51:00 -0400</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/10/31/How_to_split_a_music_file_givena_.cue_file.</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
This is the second time I needed to do this, so instead of googling again, I thought that I may post it here for future reference .....
</p>

<p>
Thanks to fl_bulgarelli from the Fedora Forum here is a small how to, when somebody gives you a complete album encoded in flac and a the corresponding .cue file, while what you want is to be able to split the album into smaller music files corresponding to the songs.
</p>

<p>
The magic command is: <code>cuebreakpoints album.cue | shnsplit -o flac album.flac</code>
</p>

<p>
More details about how to set this up, can be found <a href="http://forums.fedoraforum.org/showthread.php?t=163578">here</a>. (For the shake of completeness I will add that the cuetools package is available to install via yum. You will need to compile shntool though)
</p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-4992397180172693446?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: Fedora: Using and authenticating yum through a proxy</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/09/29/Fedora:_Using_and_authenticating_yum_through_a_proxy</link>
		<pubDate>Tue, 29 Sep 2009 09:17:00 -0400</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/09/29/Fedora:_Using_and_authenticating_yum_through_a_proxy</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
I have just finished a Fedora 11 installation here at the office. We needed a test bed for working with <a href="http://www.symfony-project.org">symfony</a> and our EL machines did not provide php 5.2.
</p>
<p>
Next thing was to update the new machine and install additional software and that meant being able to go through a squid proxy server, that requires authentication.
</p>
<p>
A little bit of digging and the magic <code>man yum.conf</code> revealed the following :
</p>
<p>Edit /etc/yum.conf and add the following lines:</p>
<pre>
proxy=http://proxy.domain.local:port
proxy_username=your_user_name
proxy_password=your_password
</pre>
<p>
Needless to say that the same configuration works perfectly on CentOS 5.4 ...
</p>
<p>
When your machine is behind a proxy then, in order for many other programs -- like wget -- to function correctly,  you also need to export the <code>http_proxy</code> variable. The correct format for it is : <br><br>
<code>export <a href="http_proxy=http://username:password@proxy.domain:port">[http_proxy=http:]</a> </code>
</p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-8545459558794414090?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: Javascript : Yet an other email address validator.</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/09/11/Javascript_:_Yet_an_other_email_address_validator.</link>
		<pubDate>Fri, 11 Sep 2009 09:22:00 -0400</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/09/11/Javascript_:_Yet_an_other_email_address_validator.</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
I was building a Conduct us page the other day and run into the need for a JavaScript e-mail validator. I googled around a bit only to discover that the approaches were so many that I didn't know which one to choose.
</p>
<p>
So, eventually I did what every hard headed person would do, so I sat down amd wrote my own <code>validateEmail</code> function.  The code is a merge of ideas coming from the fifth edition of Tom Mergino's and Dori Smith's <a href="http://www.amazon.com/JavaScript-World-Wide-Web-Fifth/dp/032119439X/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1252651324&amp;sr=8-1">JavaScript for the World Wide Web</a>, and Anita Sudhakar's apprach from <a href="http://www.smartwebby.com/DHTML/email_validation.asp">SmartWebby</a>.
</p>
<p>
The resulted code looks like the following :
</p>
<pre>
function validateMail(str)
{
  var at = "@";
  var dot = ".";
  var atPos = str.indexOf(at);    // position of '@' in the string
  var stringLength = str.length;  // position of '.' after the '@'
  var dotPos = str.indexOf(dot, atPos);
  var invalidChars = "~`/!#$%^&amp;*()+={}[];:";
  var i;
  var badChar;

  // Step 1 Do not allow blank emails
  if ( str == "")
    return false;

  // Step 2 Make sure that the address does not contain invalid characters
  for (i = 0; i  -1)
      return false;
  }

  // Step 3: Make sure that the @ character is present and
  // that is not the first or the last character of the
  // email address string.
  if (atPos == -1 || atPos == 0 || atPos == stringLength)
     return false;

  // Step 4: Likewise make sure that a dot character exists and that
  // the distance between the @ and . is at least two characters apart
  if (dotPos == -1 || dotPos + 3 &gt; stringLength)
      return false;

  // we have passed all tests let's hope that the email is valid
  return true;
}
</pre>
<p>
The function should be called from an other function that will retrieve that value of an email filed and test it during form submit. A typical usage would be :
</p>
<pre>

function validateEmailField( fieldID)
{
  var emailField = document.getElementById( eMailFieldID);
  var status = false;

  if (validateMail(emailField.value))
    status = true;
  else
    alert('Invalid email!');
  
  return status;
}
</pre><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-1233737509105568288?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: Windows: The ultimate way to get rid of stuck print jobs.</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/09/04/Windows:_The_ultimate_way_to_get_rid_of_stuck_print_jobs.</link>
		<pubDate>Fri, 04 Sep 2009 15:20:00 -0400</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/09/04/Windows:_The_ultimate_way_to_get_rid_of_stuck_print_jobs.</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
Sometimes print jobs get stuck for good. Users try to delete them and then the entire queue gets stuck too. I have many times tried to find a remedy for that and even attempted to reboot the Windows server in question without always achieving the desired result. Lately, my eyes were opened by a friend who showed me they way by following the steps shown below.
<p>
<ol>
<li>Stop the Print Spooler service.</li>
<li>Delete all files from <code>%SystemRoot%\system32\spool\PRINTERS/</code>.</li>
<li>Start the Print Spooler Service again.</li>
</ol>
<p>
... and that does it.
<p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-8395160291937921939?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: Windows: Shutting down machines remotely</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/09/02/Windows:_Shutting_down_machines_remotely</link>
		<pubDate>Wed, 02 Sep 2009 09:08:00 -0400</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/09/02/Windows:_Shutting_down_machines_remotely</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
I have many times heard people complain about Windows machines freezing or being very slow to respond. The problem sometimes is so bad that not even the desktop user is able to close frozen applications or even shutdown her own machine. The remedy for 99% of all these cases, thank you Microsoft, -- as <a href="http://www.minasi.com/">Mark Minasi</a> would have said -- is the notorious <code>shutdown</code> command.
</p>
<p>
This posting will contain a brief overview of the command syntax. This command has been around since the days of Windows NT4  but Microsoft has changed it and now in Windows 2003 environments the arguments are not the same
</p>
<p>
So, to begin with the oldest version for those of us still stuck with NT4, the syntax for this platform is like this
<p>
<pre>
shutdown \\machine_name /r /t:10 "Machine is going down in 10 seconds" /y /c
</pre>
<p>
You can also use the /l switch to force a local shutdown. The /c, shown above, is very useful since it forces all running applications to close. The -t:N will display a message notifying the user that their machine is going down in N seconds. Here you can also provide an additional string explaining the reasons for the reboot, enclosed in double quotes.  Finally if you forget the /r then the machine will just shutdown and then you 'll have to walk over there and power it down -- remember, this is NT4 we 're talking about --  and then up yourself. If after all you change your mind and you decide that the machine does not need to reboot, then -- if there is still enough time left --  use the command <code>shutdown \\machine_name /A</code> to abort the shutdown process.
</p>
<p>
Now with Windows 2003 the shutdown command has changed quite a bit. The equivalant command to shutdown a remote system now looks like this:
</p>
<pre>
shutdown /r /m \\machine_name /t 10 /f /c "Machine is going down in 10 seconds"
</pre>
<p>
The order of the arguments is significant. The /r switch can be replaced with /s to shutdown or /a to abort a shutdown in progress. The /t and the time interval are now separated by a space instead of a column ':' character. The /c switch now introduces the message for the shutdown reason and finally /f is now used to force closing of all running applications.
</p>
<p>
Shutdown for Windows 2003 has also an additional /d [p:]xx:yy switch that allows you to specify a coded reason for the shutdown, in exactly the same way you do when shutting down a Windows 2003 server via the GUI. The shutdown help screen provides detailed code listings about the meaning of each code. I never use them from the command line, so my most often issued command looks like this :
</p>
<pre>
shutdown /r /m \\pc-bakalidis /t 0 /f 
</pre><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-6922890445639189055?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: CentOS: Problems updating python</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/09/01/CentOS:_Problems_updating_python</link>
		<pubDate>Tue, 01 Sep 2009 10:12:00 -0400</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/09/01/CentOS:_Problems_updating_python</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
I have been running into the same problem while trying to update my 5.3 CentOS machine. 
</p>
<p>
Yum reported three packages that needed update :
</p>
<pre>
 java-1.6.0-openjdk     x86_64     1:1.6.0.0-1.2.b09.el5      updates      27 M
 libxml2-python         x86_64     2.6.26-2.1.2.8             updates     713 k
 python                 x86_64     2.4.3-24.el5_3.6           updates     5.9 M
</pre>
<p>
When <code>yum update</code> was issued however, the same error message kept popping up.
</p>
<pre>
--&gt; Missing Dependency: /usr/lib64/python2.4 is needed by package
libxslt-python-1.1.17-2.el5_2.2.x86_64 (installed)
</pre>
<p>
I tried disabling almost all my repositories, I removed many packages, almost ended up un-installing half my entire and then I googled on it. As always,, the answer was right there in front of me. <a href="http://www.linux-archive.org/centos/352695-yum-update-problems-python-x86_64-centos-5-3-a.html">Frank Cox</a> wrote on the CentOS mailing list:
<pre>
yum clean all
yum update
</pre>
<p>
And that works. Thank you Frank.
</p>
</p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-897610086248588185?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: Linux: Safely deleting .rpmnew files</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/06/12/Linux:_Safely_deleting_.rpmnew_files</link>
		<pubDate>Fri, 12 Jun 2009 10:18:00 -0400</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/06/12/Linux:_Safely_deleting_.rpmnew_files</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
Just got on my hands on the new Fedora 11 today. I have to admit that I didn't get a chance to explore all the <a href="http://docs.fedoraproject.org/release-notes/f11/en-US/">new</a> things that Leonidas has brought along. 
</p>
<p>
For starters, the feature that amazed me was the preupgrade script that magically downloaded everything, installed it and even changed my repos to point to correct ones for Fedora 11. And when I say repos, I do not mean only the basic ones, but also livna and RPM Fusion.
</p>
<p>
So the next thing that I had in my mind was to check all the .rpmnew files installed in my system and determine what was needed, so I started doing a search with a command like <code>find / -name *.rpmnew -print</code>, I ended up using diff and deleting the .rpmnew file that was identical to the original.
</p>
<p>
After comparing /usr/share/config/colors/Royal.colors.rpmnew, /usr/share/config/colors/40.colors.rpmnew, /usr/share/config/colors/Web.colors.rpmnew and /usr/share/config/colors/Rainbow.colors.rpmnew with their original versions and deleting all four of them, I decided that a little script could save me quit a lot of trouble. So after a little bit of digging I ended up with the following code:
</p>
<pre>
#!/bin/bash

# Locate all *.rpmnew files in your system and compares them with the 
# original files without the rpmnew extention. 
# Files are then compared using diff. If their contents are the same, then
# the .rpmnew version is removed.

RPM_NEW_LIST=`find / -name "*.rpmnew" -print 2&gt;/dev/null`

for RPMNEW_FILE in $RPM_NEW_LIST
do
    # Get the file without the .rpmnew extention
    ORIGINAL_FILE=${RPMNEW_FILE%".rpmnew"}
    # Compare it with the original
    DIFFERENT=`diff $RPMNEW_FILE $ORIGINAL_FILE`
    # If diff's answer is not empty ...
    if [ -n "$DIFFERENT" ]; then
        echo "Please examnine files $ORIGINAL_FILE and $RPMNEW_FILE "
    else
        # File is safe to remove
        # rm -f -v $RPMNEW_FILE
        echo "$RPMNEW_FILE file can safely be removed." 
    fi
done
</pre>

<p>
I run this script as root on both my Fedora and CentOS 5.3 machines The simple version I have here will show you the files that are safe to delete and the files need your attention. If you like, you can uncomment the rm -fv line at the end of the script, but I would strongly advice against it.
</p>
<p>
Note: Sometimes rpm leaves out .rpmsave files as well so, if you are really into cleaning up your system, it is wise to search for these files also.
</p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-3435422568135091767?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: Linux: File containing active DHCP leases</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/05/03/Linux:_File_containing_active_DHCP_leases</link>
		<pubDate>Sun, 03 May 2009 20:01:00 -0400</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/05/03/Linux:_File_containing_active_DHCP_leases</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<ul>
<li>On openSUSE systems this is located in <code>/var/lib/dhcp/db/dhcpd.leases</code> </li>
<li>On CentOS the leases file is in: <code>/var/lib/dhcpd/dhcpd.leases</code></li>
</ul>
<p>
As soon as I find out what goes on on other systems, I 'll make new entries as needed. 
</p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-7703067154692904633?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: Oracle 11g: Switching to native compilation</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/04/16/Oracle_11g:_Switching_to_native_compilation</link>
		<pubDate>Thu, 16 Apr 2009 12:50:00 -0400</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/04/16/Oracle_11g:_Switching_to_native_compilation</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
One of the most <i>celebrated</i> features of Oracle 11g is supposed to be the PL/SQL native compilation feature. This allows PL/SQL code to be compiled directly into machine code that is also stored inside the database, thus eliminating the need for an external C complier of DLL loader. 
</p>
<p>
Sam R. Alapati and Charles Kim in their <a href="http://www.amazon.com/Oracle-Database-11g-Features-Developers/dp/1590599101/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1239877147&amp;sr=8-1">Oracle Database 11g New Features for DBA's and Developers</a> book published by APRESS, write that tests performed by Oracle showed an increase in performance of up to 20 times when using native SQL.
</p>
<p>
There is only one startup parameter that affects the compilation mode of new PL/SQL programs. This parameter is named <code>plsql_code_type</code> and its value can be either 'NATIVE' or 'INTERPRETED'. So doing an :
</p> 
<pre>
SQL&gt; alter system set plsql_code_type = 'NATIVE' scope=both;

System altered.

SQL&gt; 
</pre>
<p> 
... will effect all new PL/SQL programs that will be created or compiled from this point on. Switching the entire database to use native PL/SQL is a bit more complicated and is performed by following these steps :
</p>
<ol>
<li> Shutdown the database.</li>
<li> Start it up again in upgrade more. (<code>startup upgrade</code>) </li>
<li> Run the <code>$ORACLE_HOME/rdbms/admin/dbmsupgnv.sql</code> script. This will set the execution mode of all database PL/SQL code blocks to native.</li>
<li> Shutdown the database and start it up again in normal mode. </li>
<li> Run the <code>$ORACLE_HOME/rdbms/admin/utlrp.sql</code> script to recompile all invalid PL/SQL code units.</li>
</ol>
<p>
Be advised that the last step may take a considerable amount of time, depending on the number of PL/SQL objects in your database. Oracle provides the following query to test the number of objects left to be compiled.
</p>
<pre>
SQL&gt;  SELECT COUNT(*) FROM obj$ WHERE status IN (4, 5, 6);

  COUNT(*)
----------
      2055

SQL&gt; r   
  1*  SELECT COUNT(*) FROM obj$ WHERE status IN (4, 5, 6)

  COUNT(*)
----------
      2005

SQL&gt; r
  1*  SELECT COUNT(*) FROM obj$ WHERE status IN (4, 5, 6)

  COUNT(*)
----------
      1109

SQL&gt;
</pre>
</p>
One last thing. The process can be reversed, by following the steps above but instead of running <code>dbmsupgnv.sql</code>, run the <code>dbmsupgin.sql</code> also located in <code>$ORACLE_HOME/rdbms/bin</code>.<img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-7445734462349527144?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: Linux: Getting passed rsync's most notorious error messages and determining whether a shell is interactive or not.</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/04/07/Linux:_Getting_passed_rsync_s_most_notorious_error_messages_and_determining_whether_a_shell_is_interactive_or_not.</link>
		<pubDate>Tue, 07 Apr 2009 16:13:00 -0400</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/04/07/Linux:_Getting_passed_rsync_s_most_notorious_error_messages_and_determining_whether_a_shell_is_interactive_or_not.</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
While trying to back up my personal data using <code>rsync -aruvzh --delete  /home/thanassis/jdevhome/ thanassis@192.168.1.68:/home/thanassis/jdevhome</code> I run into the following error message.
</p>
<pre>
protocol version mismatch - is your shell clean?
(see the rsync man page for an explanation)
rsync error: protocol incompatibility (code 2) at compat.c(69)
</pre>
<p>
A little googling and a final look at the rsync manual revealed that :
</p>
<pre>
DIAGNOSTICS
     rsync occasionally produces error messages that may seem a little cryp-
     tic.  The  one that seems to cause the most confusion is “protocol ver-
     sion mismatch — is your shell clean?”.

     This message is usually caused by your startup scripts or remote  shell
     facility  producing  unwanted garbage on the stream that rsync is using
     for its transport. The way to diagnose this  problem  is  to  run  your
     remote shell like this:

            ssh remotehost /bin/true &gt; out.dat

     then  look  at out.dat. If everything is working correctly then out.dat
     should be a zero length file. If you are getting the above  error  from
     rsync  then  you  will probably find that out.dat contains some text or
     data. Look at the contents and try to work out what  is  producing  it.
     The  most  common cause is incorrectly configured shell startup scripts
     (such as .cshrc or .profile) that contain output  statements  for  non-
     interactive logins.
</pre>
<p>
Needless to say that fortune was the one to blame. My .bashrc file had the following last statements since the days of SuSE 8.2 and although I am now using a completely different distro, I still refuse to get them out of my startup files.
</p>
<pre>
# Something to remember the old SuSE days
if [ -x /usr/bin/fortune ] ; then
    echo
    /usr/bin/fortune
    echo
fi
</pre>
<p>
So, the solution would be to display a fortune cookie only when the current shell is interactive and then it was time for the <a href="http://www.gnu.org/software/bash/manual/bashref.html#Is-this-Shell-Interactive_003f">Bash Reference Manual</a> to come to our rescue. Their answers are straightforward : 
</p>
<blockquote>
To determine within a startup script whether Bash is running interactively or not, examine the variable $PS1; it is unset in non-interactive shells, and set in interactive shells. Thus:
</blockquote>
<pre>
     if [ -z "$PS1" ]; then
        echo This shell is not interactive
     else
        echo This shell is interactive
     fi
</pre>
<blockquote>
Alternatively, startup scripts may test the value of the `-' special parameter. It contains i when the shell is interactive. For example:
</blockquote>
<pre>
     case "$-" in
     *i*)  echo This shell is interactive ;;
     *)    echo This shell is not interactive ;;
     esac
</pre>
<p>
In my case I wanted to run fortune on interactive shells only. So
again I modified my bashrc file to look like :
</p>
<pre>
# Display a fortune cookie on interactive logins only
if [ -n "$PS1" ]; then
        # Some people don't like fortune. If you uncomment the following lines,
        # you will have a fortune each time you log in ;-)
        if [ -x /usr/bin/fortune ] ; then
                echo
                /usr/bin/fortune
                echo
        fi
fi

</pre>
</p>
<p> 
... and that did it.
</p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-7853336038829587317?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: JDevelopr 10g to 11g. It's a long way to migration</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/03/27/JDevelopr_10g_to_11g._It_s_a_long_way_to_migration</link>
		<pubDate>Fri, 27 Mar 2009 18:04:00 -0400</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/03/27/JDevelopr_10g_to_11g._It_s_a_long_way_to_migration</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
  Today i tried migrating a simple project from JDeveloper 10g (10.1.3.4) to 11g (11.1.1.0.1) )and the results are mostly disappointing.
</p>
<p>
A picture is a thousand words.
</p>
<table>

 Migration Results

<tr>
  <th>
     Browse Page
  </th>
</tr>
<tr>
<td>
<a href="http://2.bp.blogspot.com/_CFT56hwlD5g/SczsN6l486I/AAAAAAAAALk/YEW05k8gdZw/s1600-h/Screenshot-JDev+10g.png"><img src="http://2.bp.blogspot.com/_CFT56hwlD5g/SczsN6l486I/AAAAAAAAALk/YEW05k8gdZw/s400/Screenshot-JDev+10g.png" /></a>
</td>
<td>
<a href="http://4.bp.blogspot.com/_CFT56hwlD5g/SczsrurXXDI/AAAAAAAAALs/JSCXzjQrLk8/s1600-h/Screenshot-JDev11g.png"><img src="http://4.bp.blogspot.com/_CFT56hwlD5g/SczsrurXXDI/AAAAAAAAALs/JSCXzjQrLk8/s400/Screenshot-JDev11g.png" /></a>
</td>
</tr>

<tr>
  <th>
      Search Page
  </th>
</tr>
<tr>
  <td>
    <a href="http://4.bp.blogspot.com/_CFT56hwlD5g/SdBlWEfZHAI/AAAAAAAAAL0/f7XAkg-5G1I/s1600-h/Search+10g.png"><img src="http://4.bp.blogspot.com/_CFT56hwlD5g/SdBlWEfZHAI/AAAAAAAAAL0/f7XAkg-5G1I/s400/Search+10g.png" /></a>
  </td>
  <td>
    <a href="http://1.bp.blogspot.com/_CFT56hwlD5g/SdBllTAl86I/AAAAAAAAAL8/ZnYJe2uU_nc/s1600-h/Screenshot-Search11g.png"><img src="http://1.bp.blogspot.com/_CFT56hwlD5g/SdBllTAl86I/AAAAAAAAAL8/ZnYJe2uU_nc/s400/Screenshot-Search11g.png" /></a>
  </td>
</tr>
<tr>
  <td>
    This is how the application looks today.
  </td>
  <td>
    ... and here is how it ended up after migration......
  </td>
</tr>
</table>
<p>
<p>
 Just for the shake of complicity, I have to report the following :
</p>
<ul>
  <li>
    Migration finished without any exceptions being thrown at the console. The only warning message that appears when opening the project is :
    <pre>
Mar 30, 2009 9:43:18 AM oracle.jdevimpl.webapp.taglib.JDevTaglibUtils _parseFail
WARNING: Invalid TLD Location, TldUtils parse failed for URL : jar:file:/home/oracle/jdeveloper/mywork/AS400-Materials/ViewController/opt/oracle/Middleware/jdeveloper/jlib/adf-faces-databinding-rt.jar!/META-INF/databinding.tld
    </pre>
  </li>
  <li>
    Although attribute labels are not shown in the search page, the Attribute properties page displays them correctly.
    <br>
    <a href="http://4.bp.blogspot.com/_CFT56hwlD5g/SdBoM5JeAvI/AAAAAAAAAME/r7-2u3eH268/s1600-h/Screenshot-Edit+Attribute:+Plant.png"><img src="http://4.bp.blogspot.com/_CFT56hwlD5g/SdBoM5JeAvI/AAAAAAAAAME/r7-2u3eH268/s400/Screenshot-Edit+Attribute:+Plant.png" /></a>
  </li>
  <li>
   The initial JSF navigation diagram, does not display any graphic, despite the fact that I see no error ether on the message window or the console.
   <br>
   <a href="http://2.bp.blogspot.com/_CFT56hwlD5g/SdBr042wKQI/AAAAAAAAAMM/yLnkrmGmnGo/s1600-h/Screenshot.png"><img src="http://2.bp.blogspot.com/_CFT56hwlD5g/SdBr042wKQI/AAAAAAAAAMM/yLnkrmGmnGo/s400/Screenshot.png" /></a>
  </li>
</ul>
<p>
   I feel like I want to complain to somebody, but I am not sure to whom.
</p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-7839154373573437830?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: Linux: Mind your labels</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/03/23/Linux:_Mind_your_labels</link>
		<pubDate>Mon, 23 Mar 2009 15:16:00 -0400</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/03/23/Linux:_Mind_your_labels</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
I had seen labels used in <code>/etc/fstab</code> and <code>/boot/grub/grub.conf</code> but never quite got the hung of them, until I read page 170 of Tammy Fox's <a href="http://www.amazon.com/Red-Enterprise-Linux-Administration-Unleashed/dp/0672328925">Red Hat Enterprise Linux 5 Administration Unleashed</a>.
</p>
<p>
So what I got out of this, was that labels may be listed in place of partitions and while they are not required, they may become useful when a partition number changes, when moving the partition or repartitioning the drive.
</p>
<p>
The command to use for changing or displaying a partition's label is <code>e2label</code>. The command must be run as root and the syntax is as simple as :
</p>

e2label device [newlabel

<p>
This sets label to device and if no label is provided, then the device's label is displayed. 
</p>
<p>
So far so good. Now the sad story begins when attempting to change the label of an existing partition of an already used drive, especially the one containing /boot.
</p>
<p>
When that happens remember to update both /etc/fstab and /boot/grub/grub.conf. Otherwise you risk not being able to boot your system next time. The default label used by the Anaconda installer is "\". So let's suppose that for some reason you decide to change this to CentOS-Root, by issuing something like :
</p>
<pre>
[root@lxbakalidis ~]# e2label /dev/sda1 CentOS-Root
</pre>
<p>
Next thing to do is check your /etc/fstab file and make sure that an entry like :
</p>
<pre>
LABEL=CentOS-Root       /                       ext3    defaults        1 1
</pre>
<p>
is really there and last but not least make sure that grab.conf line that starts your current kernel also references the new label like this:
</p>
<pre>
title CentOS (2.6.18-92.1.22.el5)
        root (hd1,0)
        kernel /boot/vmlinuz-2.6.18-92.1.22.el5 ro root=LABEL=CentOS-Root rhgb quiet 
        initrd /boot/initrd-2.6.18-92.1.22.el5.img

</pre>
<p>
Failure to do this right will probably halt your kernel with messages like :
</p>
<pre>
mount: could not find filesystem '/dev/root'
setuproot: moving /dev failed: No such file or directory
setuproot: error mounting /proc: No such file or directory
setuproot: error mounting /sys: No such file or directory
switchroot: mount failed: No such file or directory
Kernel panic - not syncing: Attempted to kill init!
</pre>
<p>
... and you will probably need a live CD to fix it. For more information refer to the following thread at <a href="http://www.linuxquestions.org/questions/fedora-installation-39/fc6-mount-could-not-find-filesystem-devroot-497332/">LinuxQustions.org</a>.
<p>
<p>
PS: Now I am sure that the last fortune cookie I saw  before the crush read something like Good judgement comes from experience, experience comes from bad judgement.  but I was too preoccupied with the coming Friday night joys to take it seriously.<img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-1594080915431465672?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: Linux : Creating virtual disks from .iso files</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/02/13/Linux_:_Creating_virtual_disks_from_.iso_files</link>
		<pubDate>Fri, 13 Feb 2009 12:41:00 -0500</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/02/13/Linux_:_Creating_virtual_disks_from_.iso_files</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
Just picked this up from the fedora guide and and thought I might put it here for reference.
</p>
<p>
Suppose you have a .ISO file whose contents you wish to examine or even need to copy some data out of. The <a href="http://www.fedoraguide.info/index.php?title=Main_Page#How_to_Un.2FMount_an_Image_.28iso.29_without_burning_it">fedora-guide</a> suggests the following approach.
</p>
<pre>
mkdir ~/your_disc/
su -c 'mount file.iso ~/your_disc -t iso9660 -o loop'
</pre>
<p>
then to unmount it 
</p>
<pre>
su -c 'umount ~/your_disc/'
</pre><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-8060861686410311397?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: RealPlayer for 64 bit Linux</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/02/05/RealPlayer_for_64_bit_Linux</link>
		<pubDate>Thu, 05 Feb 2009 20:28:00 -0500</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/02/05/RealPlayer_for_64_bit_Linux</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
This is quick note to myself as I keep forgetting it.
</p>
<p>
The location to download latest nightly builds for RealPlayer that includes a x86_64 version for Linux is
<a href="http://forms.helixcommunity.org/helix/builds/?category=realplay-current">here</a>.
</p>
<p>
For x86_64 Linux choose the version tagged <code>linux-2.6-glibc23-amd64</code>.
</p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-7655323975010479821?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: Linux: Getting past the "BIOS doesn't leave a aperture memory hole" error or "How to enable the IOMMU option in the BIOS setup" . Part 2</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/01/08/Linux:_Getting_past_the__BIOS_doesn_t_leave_a_aperture_memory_hole__error_or__How_to_enable_the_IOMMU_option_in_the_BIOS_setup__._Part_2</link>
		<pubDate>Thu, 08 Jan 2009 10:45:00 -0500</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/01/08/Linux:_Getting_past_the__BIOS_doesn_t_leave_a_aperture_memory_hole__error_or__How_to_enable_the_IOMMU_option_in_the_BIOS_setup__._Part_2</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
      After <a href="http://abakalidis.blogspot.com/2009/01/linux-getting-past-bios-doesnt-leave.html">yesterdays</a> post regarding the BIOS doesn't leave a aperture memory hole issue, I got a very logical question that I forgot to ask myself as I was too happy to see the error message go away.
    </p>
    <blockquote>
      <a href="http://www.blogger.com/profile/12132179834912519990">Quirinius</a> said:
      <br><br>
      But did that boot option actually give you more memory? Did you check with "free -m"?
    </blockquote>
    <p>
      So I did a little bit of testing. Here is the output of the free command before the using boot-options on the CentOS machine.
    </p>
    
    <pre>
  total       used       free     shared    buffers     cached
Mem:       4048440     804072    3244368          0      34324     428640
-/+ buffers/cache:     341108    3707332
Swap:      4200988          0    4200988
      
  total       used       free     shared    buffers     cached
Mem:          3953        785       3168          0         33        418
-/+ buffers/cache:        333       3620
Swap:         4102          0       4102
    </pre>
    
    <p>
      and here is after :
    </p>
    
    <pre>
  total       used       free     shared    buffers     cached
Mem:       4048024     553232    3494792          0      30792     336400
-/+ buffers/cache:     186040    3861984
Swap:      4200988          0    4200988
      
  total       used       free     shared    buffers     cached
Mem:          3953        536       3416          0         30        328
-/+ buffers/cache:        177       3775
Swap:         4102          0       4102
    </pre>
    
    <p>
      I have also checked what is happening on my notebook which also has 4GB of RAM memory but unlike the rest of my machines does not have an AMD processor or an Asus Motherboard with Phoenix BIOS and here is what free had to say.
    </p>
    
    <pre>
  total       used       free     shared    buffers     cached
Mem:       4059392     652816    3406576          0      13048     206600
-/+ buffers/cache:     433168    3626224
Swap:      2096472          0    2096472
      
  total       used       free     shared    buffers     cached
Mem:          3964        637       3326          0         12        201
-/+ buffers/cache:        423       3541
Swap:         2047          0       2047
    </pre>
    
    <p>
      Doing a little bit of math shows that ...
    </p>
    <pre>
      [thanassis@lxbakalidis ~]$ expr 4048024 - 4048440
      -416
    </pre>
    <p>
      After the boot option is set our memory decreases by 416 bytes and the memory reported by Fedora on a system that does not display the IOMMU error message at all is
    </p>
    <pre>
      [thanassis@lxbakalidis ~]$ expr 4059392 - 4048440
      10952
    </pre>
    <p>
      ... bytes bigger. Now I understand that I am comparing results from two different kernel versions, so I performed the same test at home on my AMD/Asus based Fedora box and here are my results..
    <p>
    
    <pre>
[thanassis@plouton ~]$ cat fedora-home-before.txt 
             total       used       free     shared    buffers     cached
Mem:       4062232     490440    3571792          0      13816     177132
-/+ buffers/cache:     299492    3762740
Swap:            0          0          0
             total       used       free     shared    buffers     cached
Mem:          3967        479       3488          0         13        172
-/+ buffers/cache:        292       3674
Swap:            0          0          0
[thanassis@plouton ~]$ cat fedora-home-after.txt 
             total       used       free     shared    buffers     cached
Mem:       4061820    1083232    2978588          0      34960     393808
-/+ buffers/cache:     654464    3407356
Swap:            0          0          0
             total       used       free     shared    buffers     cached
Mem:          3966       1055       2910          0         34        384
-/+ buffers/cache:        636       3329
Swap:            0          0          0
[thanassis@plouton ~]$ expr 4061820 - 4062232
-412
[thanassis@plouton ~]$ 
    </pre>
    

Addendum

    <p>
     This is only a closing statement to admit that I managed nothing. I tried 
changing my graphics adapter with a new NVIDIA using the new kernel updates and my CentOS machine just froze again. 
    </p>
    <p>
So I switched everything back, got my 416 bytes back and try to keep an eye on the net and the forums in case I somehow find something to help me this.... :-(
    </p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-4812453622750031523?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item><item>
		<title>Programming and DBA: Linux: Getting past the "BIOS doesn't leave a aperture memory hole" error or "How to enable the IOMMU option in the BIOS setup" .</title>
		<link>http://www.komotiniblogs.gr/Programming_and_DBA/2009/01/06/Linux:_Getting_past_the__BIOS_doesn_t_leave_a_aperture_memory_hole__error_or__How_to_enable_the_IOMMU_option_in_the_BIOS_setup__.</link>
		<pubDate>Tue, 06 Jan 2009 19:27:00 -0500</pubDate>
		<guid>http://www.komotiniblogs.gr/Programming_and_DBA/2009/01/06/Linux:_Getting_past_the__BIOS_doesn_t_leave_a_aperture_memory_hole__error_or__How_to_enable_the_IOMMU_option_in_the_BIOS_setup__.</guid>
				<author>Athanassios Bakalidis</author>		
				<content:encoded><![CDATA[	<p>
This had been a major <i>"To Do"</i> item for me during the last year and I have tried many times to fix it, but today it seems I got lucky.
</p>
<p>
I had been seeing this on my CentOS workstation <code>dmesg</code> output, since the first day I installed it, approximately one year ago.
</p>

<pre>
Checking aperture...
CPU 0: aperture @ 14000000 size 32 MB
Aperture too small (32 MB)
No AGP bridge found
Your BIOS doesn't leave a aperture memory hole
Please enable the IOMMU option in the BIOS setup
This costs you 64 MB of RAM
</pre>

<p>
At first I thought it was nothing serious, and I tried to fix my graphics card that would not work with the NVidia provided drivers freezing the entire graphics system each time I would install them and tried to start X. I failed that too and replaced the graphics card with one from ATI. The new card  appeared to work more satisfactory, but it would also hung if I tried to load the custom drivers provided by the vendor.
</p>
<p>
When I installed Feodra 9 at home, I saw the exact same error message but my GeForce 9600 NVidia appeared to work correctly so I dropped it. Then came Fedora 10  and there we were again. At the same time I began to get tired by the sluggish performance of my CentOS graphics and decided to try once again.
</p>
<p>
But his time I was lucky : jbkt23 provided the solution at the <a href="http://fedoraforum.org/forum/printthread.php?t=186632">Fedora Forums.</a> I am only copying it here just to help others who <i>google</i> for it come up with one much match.
</p>
<p>
Put it simply, the solution is to add the <code>
iommu=noaperture</code> kernel boot parameter on your grub.conf file.
</p>

<p>
In more words, you need to edit the grub configuration file located in <code>/boot/grub/grub.conf</code> and locate the line that boots the current kernel. On my Fedora system the line looks like this :

<pre>
title Fedora (2.6.27.9-159.fc10.x86_64)
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.27.9-159.fc10.x86_64 ro root=UUID=8a9d59ee-c401-41bf-a4e6-8fdd97
067215 rhgb quiet iommu=noaperture
        initrd /boot/initrd-2.6.27.9-159.fc10.x86_64.img
</pre>

<p>
All I needed was to add the bolded text at the end of the kernel line. Then a reboot and as MSK61 from the Fedora forum put it: Thanks, jbkt23. Worked like a charm.
</p>
<p>
The same solution worked for the CentOS 5.2 machine at work. There is more to it however. After getting rid of the IOMMU error, I tried to enable the 3D driver for my ATI Radeon X1300. At some point it worked. After the first reboot however, things went back to their normal not working state so I had to switch back to the standard driver.
<p>
<p>
Tomorrow I will try an NVidia card that was also not working and see how it goes.
</p><img src='https://blogger.googleusercontent.com/tracker/1908110696125487216-3308800044366277111?l=abakalidis.blogspot.com' /> ]]></content:encoded>
</item></channel>
</rss>
