Showing posts with label NetCAT. Show all posts
Showing posts with label NetCAT. Show all posts

Wednesday, July 25, 2012

NetCAT

I am astonished!  Over 40 issues I reported during NetCAT 7.2 where resolved and included in the latest NetBeans 7.2 release!

In total NetCAT team reported 1019 bugs of which 37% was resolved. Awesome work done by the NetBeans developers and QE engineers.


184465Opening of npss file may block AWT
184669java.util.MissingResourceException: Can't find resource for bundle org.openide.util.NbBundle$PBundle, key org.openide.actions.PopupAction
201257InternalError: processing event: -1
203427[71cat] IndexOutOfBoundsException: Invalid line index=600 >= lineCount=1
203827Minimize TextLayout creation and processing to improve performance
2048184s - ToolbarPool$Folder.createInstance may block in waitFinished()
207247[71cat] NullPointerException at org.netbeans.modules.php.editor.nav.DeclarationFinderImpl.getReferenceSpan
207402[71cat] IllegalArgumentException: Parameter file was not normalized. Was /.. instead of /
207991Large project hangs Netbeans 7.1 indefinitely.
208322[71cat] NullPointerException at org.netbeans.modules.versioning.core.api.VCSFileProxy.createFileProxy
208623[71cat] NullPointerException at org.netbeans.modules.versioning.DelegatingVCS$DelegatingHistoryProvider.getHistory
208652Infinite loop in DirectMergeContainer
208774IllegalArgumentException: Comparison method violates its general contract!
208788IllegalStateException: startCreationOffset=694 > matchOffset=683
208931Error when changing text.
209019StringIndexOutOfBoundsException: String index out of range: 0
209327ClassCastException: javax.swing.JLabel cannot be cast to javax.swing.JMenuItem
209460NullPointerException at com.mysql.jdbc.ConnectionImpl.registerStatement
209556NullPointerException at org.netbeans.modules.subversion.ui.repository.Repository.onSelectedRepositoryChange
209594UnsupportedOperationException: Not supported yet.
209665NullPointerException at org.netbeans.modules.bugtracking.spi.BugtrackingFactory.getIssueImpl
209670NullPointerException at javax.swing.BoxLayout.preferredLayoutSize
210058NullPointerException at org.netbeans.modules.subversion.ui.commit.CommitAction$5.getCopiedFromFile
210415NullPointerException at org.netbeans.modules.editor.lib2.view.DocumentView.updateStartEndOffsets
210502AssertionError: profile
210596NullPointerException at org.tigris.subversion.svnclientadapter.javahl.AbstractJhlClientAdapter.getInfo
210628java.util.ConcurrentModificationException at java.util.AbstractList$Itr.checkForComodification
210767StringIndexOutOfBoundsException: String index out of range: 803
210976StringIndexOutOfBoundsException: String index out of range: 399
211002IllegalArgumentException: Parameter file was not normalized. Was ../../../../usr/share/php/PHPUnit instead of /usr/share/php/PHPUnit
211425java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification
211439Throwable: Using stale writer, possibly forgotten call to store, old owner Thread Thread[RepositoryUpdater.worker,1,system], new owner Thread Thread[AWT-EventQueue-0,6,IDE Main] .
211744IllegalStateException: No instance data can be specified.
211759AssertionError at org.netbeans.modules.csl.editor.hyperlink.GoToSupport.getIdentifierSpan
212120Cannot merge changes from the trunk into working copy
212237IllegalStateException: Somebody changed internal state meanwhile! Expected: Inited: false Thread: Thread[org.netbeans.modules.project.ui.ProjectTab,1,system] InProgress: true MustNotify: false Entries
212246IllegalStateException: Somebody changed internal state meanwhile! Expected: Inited: true Thread: Thread[AWT-EventQueue-0,6,IDE Main] InProgress: true MustNotify: false Entries: 0; vis. entries: 0; Inf
212278ClassCastException: [Lorg.openide.nodes.Node; cannot be cast to [Lorg.netbeans.modules.csl.navigation.ElementNode;
212431IllegalStateException: Problem in some module which uses Window System: Window System API is required to be called from AWT thread only, seehttp://core.netbeans.org/proposals/threading/
213434NullPointerException at org.netbeans.modules.html.editor.completion.HtmlCompletionProvider$DocQuery.doQuery
213441NullPointerException at org.netbeans.modules.search.ui.MatchingObjectNode.setInvalidOriginal


The NetBeans 7.2 is available for download here.

Wednesday, June 1, 2011

Wish List Sample Application:: PDO Flavor

After Jeffrey Rubinoff asked community for help on rewriting sample wish list application accompanying his tutorial Creating a Database Driven Application With NetBeans IDE PHP Editor number of users raised question why PDO was not used instead of mysqli and OCI8.

During the NetCat 7.0 I had a chance to review Jeff's tutorial. I could not resist to try installing PDO_OCI. Having everything needed running on my Ubuntu box, I was finally able to do what I promised: Create PDO database class. The key objective was to make it easy to switch between MySQL and Oracle XE, preferably just by changing connection string.

Problems

Before porting WishDB class to PDO due to differences between Oracle XE and MySQL queries needed to be normalized. There are two differences affecting Wish List Sample Application:

  • Oracle is case insensitive to object names, and Oracle schema object names are stored as uppercase
  • There is a difference in handling dates between MySQL and Oracle XE
Further on, in few cases database specific PHP functions where used outside WishDB class. Such usage is hardening code maintenance and porting code to PDO. Therefore those cases had to be resolved as well before porting WishDB class.
Finally, if data could be retrieved in a single query don't query database multiple times. Establishing connection with database is bottleneck in every PHP database driven application.

Restructuring the Code

Here is an example:
// MySQL version
        $wisher = $this->query("SELECT id FROM wishers WHERE name = '"
                        . $name . "'");

        // OCI8 version
        $query = "SELECT ID FROM wishers WHERE name = :user_bv";

        // PDO version
        $query = "
            SELECT id ID
            FROM wishers
            WHERE name = :user_bv
            ";
Schema object names in MySQL version of the application are written lowercase. Oracle XE will not have a problem with lowercase names but returned array keys will be uppercase. I decided to add uppercase column names alias and use OCI8 version of the application as base for refactoring. In this way there is no need to change MySQL schema nor PHP code other then WishDB class.

Handling dates is a bit trickier. Both MySQL and Oracle XE store dates internally as timestamp. However, input and output need to be formatted differently. Logical step was to create functions having same names, input parameters and outputting identically formatted date string.

Before creating SQL functions I had to normalize function format_date_for_sql first. I prefer using DateTime class over native PHP functions.
// MySQL version
    function format_date_for_sql($date) {
        if ($date == "")
            return null;
        else {
            $dateParts = date_parse($date);
            return $dateParts['year'] * 10000 + $dateParts['month'] * 100 + $dateParts['day'];
        }
    }

    // OCI8 version
    function format_date_for_sql($date) {
        if ($date == "")
            return null;
        else {
            $dateParts = date_parse($date);
            return $dateParts['year'] * 10000 + '-' + $dateParts['month'] * 100 + '-' + $dateParts['day'];
        }
    }

    // PDO version
    function format_date_for_sql($date)
    {
        if ($date == "") {
            return null;
        } else {
            $dateTime = new DateTime($date, new DateTimeZone("UTC"));
            return $dateTime->format("Y-n-j H:i:s e");
        }
    }


Here are those two SQL functions:

// MySQL version
CREATE DEFINER=`root`@`localhost` FUNCTION  `wishlist`.`format_due_date`(
`in_date` VARCHAR(255) CHARSET latin1
) RETURNS varchar(255) CHARSET latin1
    SQL SECURITY INVOKER
BEGIN
return CONCAT(in_date, SPACE(1), 'UTC');
END $$

CREATE DEFINER=`root`@`localhost` FUNCTION  `wishlist`.`set_due_date`(
`in_date` VARCHAR(255) CHARSET latin1
) RETURNS varchar(255) CHARSET latin1
    SQL SECURITY INVOKER
BEGIN
return SUBSTR(in_date, 1, length(in_date) - 4);
END $$

// Oracle XE version
CREATE OR REPLACE
FUNCTION "FORMAT_DUE_DATE" (in_date in TIMESTAMP) return VARCHAR2 is
begin
return TO_CHAR(IN_DATE, 'YYYY-MM-DD HH24:MI:SS TZR');
end; /

CREATE OR REPLACE
FUNCTION "SET_DUE_DATE" (in_date in VARCHAR2) return VARCHAR2 is
begin return TO_TIMESTAMP_TZ(in_date, 'YYYY-MM-DD HH24:MI:SS TZR');
end; /
Finally queries could be normalized.
// MySQL version
        $this->query("INSERT INTO wishes (wisher_id, description, due_date)" .
                " VALUES (" . $wisherID . ", '" . $description . "', "
                . $this->format_date_for_sql($duedate) . ")");

        // OCI8 version
        $query = "INSERT INTO wishes (wisher_id, description, due_date) VALUES (:wisher_id_bv, :desc_bv, to_date(:due_date_bv, 'YYYY-MM-DD'))";

        // PDO version
        $query = "
            INSERT INTO wishes (wisher_id, description, due_date)
            VALUES (
                :wisher_id_bv,
                :desc_bv,
                set_due_date(:due_date_bv)
                )
            ";
User's wish list is retrieved in two steps: First, a user #id is found by user name and later on list of wishes is found by a user #id.
$wisherID = WishDB::getInstance()->get_wisher_id_by_name($_SESSION['user']);
                $stid = WishDB::getInstance()->get_wishes_by_wisher_id($wisherID);
User's wish list could be retrieved in a single query. Oracle XE supports full outer join but, unfortunately, MySQL does not. Therefore, a query has to be a bit more complex.
SELECT w.id ID, w.description DESCRIPTION,
            format_due_date(w.due_date) DUE_DATE, wr.id WRID
            FROM wishes w RIGHT OUTER JOIN wishers wr
            ON wr.id = w.wisher_id
            WHERE wr.name = :user_bv
Finally, I replaced function get_wishes_by_wisher_id with function get_wishes_by_wisher_name
/**
     * Gets user's wishes for the user having given name
     *
     * @param string $name
     * @return ArrayIterator
     */
    public function get_wishes_by_wisher_name($name)
    {
        $query = "";
        $stid = null;
        $row = array();
        $result = null;

        $query = "
            SELECT w.id ID, w.description DESCRIPTION,
            format_due_date(w.due_date) DUE_DATE, wr.id WRID
            FROM wishes w RIGHT OUTER JOIN wishers wr
            ON wr.id = w.wisher_id
            WHERE wr.name = :user_bv
            ";

        $stid = $this->con->prepare($query);
        $stid->bindParam(":user_bv", $name, PDO::PARAM_STR);
        $stid->execute();

        $result = new ArrayIterator();
        while ($row = $stid->fetch(PDO::FETCH_ASSOC)) {
            $result->append($row);
        }
        $result->rewind();

        return $result;
    }
Function get_wishes_by_wisher_name is returning ArrayIterator instead of resultset, letting me to use the same code regardless of database sitting in backend and having more clear code when displaying results.
<table class="std">
            <tr>
                <th>Item</th>
                <th>Due Date</th>
                <th colspan="2">&nbsp;</th>
            </tr>
            <?php
            $wishes = WishDB::getInstance()->
                    get_wishes_by_wisher_name($_SESSION["user"]);
            while ($wishes->valid()):
                $row = $wishes->current();
                $date = new DateTime($row['DUE_DATE'], new DateTimeZone("UTC"));
                if (true === is_null($row["ID"])) {
                    $wishes->next();
                    continue;
                }
                ?>
                <tr>
                    <td>&nbsp;
                        <?php
                        echo htmlentities($row['DESCRIPTION']);
                        ?>
                    </td>
                    <td>&nbsp;
                        <?php
                        echo (is_null($row['DUE_DATE']) ?
                                "" : $date->format("Y, M jS"));
                        $wishID = $row['ID'];
                        ?>
                    </td>
                    <td>
                        <form name="editWish"
                              action="editWish.php" method="GET">
                            <input type="hidden"
                                   name="wishID"
                                   value="<?php echo $wishID; ?>" />
                            <input type="submit" name="editWish" value="Edit" />
                        </form>
                    </td>
                    <td>
                        <form name="deleteWish"
                              action="deleteWish.php" method="POST">
                            <input type="hidden"
                                   name="wishID"
                                   value="<?php echo $wishID; ?>" />
                            <input type="submit"
                                   name="deleteWish"
                                   value="Delete" />
                        </form>
                    </td>
                </tr>
                <?php
                $wishes->next();
            endwhile;
            ?>
        </table>
You can grab the code from Kenai repository.

There is more to be done, for example all input variables must be filtered. You are warmly welcomed to join Wish List Sample Application project.

Tuesday, November 9, 2010

NetCAT 7.0 Started

NetBeans IDE 7.0 Community Acceptance Testing program officially started yesterday.

The goal of NetCAT 7.0 program is very simple: stabilize NetBeans IDE 7.0. Over seventy active NetBeans community members will be involved in testing the NetBeans IDE development builds during next four months.

This is a brief time schedule of important announcements, milestones and tasks:
  • 11/1 - Program announced on nbusers and nbdev lists. Volunteers joining NetCAT.
  • 11/8 - NetCAT team starts testing daily builds.
  • 11/12 - NetBeans 7.0 Beta #1 release
  • 11/16 - First weekly report sent.
  • 12/24 - 12/31 - Christmas break
  • 1/18 - NetBeans 7.0 Beta #2 release
  • 1/19 - Early CA research
  • 1/20 - Documentation review
  • 1/28 - Final CA survey questions defined.
  • 2/10 - NetBeans 7.0 RC release, CA survey opened
  • 2/28 - CA survey closed, results processed.
  • 3/1 - Last weekly report sent.
  • 3/8 - NetBeans 7.0 FCS release, NetCAT game over