Netbeans IDE 6.0 Beta 1 Available for Download

Programming, Ruby on Rails No Comments »

Not sure if it’s actually released or not but if you’re looking for a snappy and complete IDE for Ruby on Rails you should try Netbeans 6.0 in the Ruby flavor, a mere 19 MB download (well, you’ll need a JDK too). The joy of RoR development is greatly enhanced by such an intelligent IDE where Ruby and Rails take center stage instead of being added as an afterthought as with some competing offerings. It’s amazing that the developer team was able to iron out quite a number of bugs in the two weeks since I downloaded a nightly built. Other people like it too.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Replicating a Subversion Repository to a Windows Target Server via Synchronization

Computing, Programming, Subversion 5 Comments »

To backup, replicate or mirror a repository is arguably one of the most important tasks working with Subversion. Of course a repository folder is completely self-contained and can be copied or ftped to a different location and read by svn without any problems as long as there is no writing or locking going on. Besides the simple copy there are several safer and more svn-specific options, three of which are discussed in this article. However, the suggested svnadmin hotcopy command like most svnadmin works only with paths, not URLs. So you have to enter (Windows):

C:\>svnadmin hotcopy c:\myrepos \\MYBACKUPSERVER\C\myrepos_bak

This technique works fine on your local network where you have path access as it’s fast and simple to use.

Since version 1.4 Subversion offers the svnsync utility which maintains read-only mirror of a subversion repository at a (remote) URL. It words by replaying revisions of the original (source/master) repository at a mirror (sink) repository.

The setup notes are meant for Unix machines and not easy to understand for newbies. Follow these steps to get it working on a Windows machine:

  1. Set up a sync user on the destination repository by editing the passwd file in the conf directory of the target repository:
    [users]
    #harry = harryssecret
    #sally = sallyssecret
    mysvnsyncuser = mystrongpassword
  2. This “syncuser” you created must be allowed to change revprops of the destination repository used by svnsync to keep track of bookkeeping information. Therefore a pre-revprop-change hook script has to be created. You will find an example script in the /hooks/pre-revprop-change.tmpl file of your target repository. However, this script is a Unix shell script and will not work under Windows. You will get the following error if you don’t have a script in the hooks folder that can be executed by Windows:

    svnsync: Repository has not been enabled to accept revision propchanges;
    ask the administrator to create a pre-revprop-change hook

    The simple solution is just to create a file named pre-revprop-change.bat containing the single line:
    @exit 0
    and save this file file in the /hooks directory of the target repository.

  3. Then svnsync has to be initialized with the command:
    svnsync init svn://mytargetserver/mytargetrepository svn://mysourceserver/mysourcerepository
    (you can use any other URL such as file:, http:, svn+ssh:)
    You will be prompted for the username and password you created for the mysvnsycuser above.
    If all went well you will get the response:
    Copied properties for revision 0
  4. You can now sync with the command:
    svnsync sync svn://mytargetserver/mytargetrepository
    and all revisions to your source repository will be replayed to the destination repository.
  5. In Windows you could set up a Scheduled Task to sync from time to time which is beyond the scope of this article.
  6. Don’t forget: NEVER commit to a synced repository without “svnsync” or you’ll get the “have you committed to the destination without using svnsync?” error and you’ll have to start over with the above process.

Hope it helps.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Working with Nested Repeaters in ASP.NET

ASP.NET, Programming No Comments »

Sometimes I miss the option that you have in classic ASP, PHP or Ruby on Rails to just put a nested loop into the html page (view, presentation layer) to display nested data. Of course this is, strictly speaking, against ASP.NET best practices where you’re supposed to use web controls for everything. Then again one could make the argument that the loop actually belongs in the view. This would be .aspx page, and not in the controller or the model (code behind file in ASP.NET).

The task at hand is to iterate through parent categories and child items. The technique suggested by Microsoft is outlined here, and this article uses a nested repeater with a self-join. Starting point is the following DataSet with two related tables and a repeater in the page:

DataSet myDS = new DataSet("NestedRepeaterDemo"); … //fill the dataset myDS.Tables[0].TableName = "ParentCategories"; myDS.Tables[1].TableName = "ChildItems"; DataRelation relation = new DataRelation("myRelation", myDS.Tables["ParentCategories"].Columns["CatID"], myDS.Tables["ChildItems"].Columns["CatID"], true); relation.Nested = true; myDS.Relations.Add(relation); parentRepeater.DataSource = myDS; parentRepeater.DataBind();

So why not bind the child repeater in the page, just for the heck of it:

<table> <asp:Repeater id="parentRepeater" runat="server"> <itemtemplate> <tr class="categoryInTable"> <td colspan="2"> <%# DataBinder.Eval(Container.DataItem, "CategoryName") %> </td> </tr> <asp:Repeater ID="childRepeater" runat="server" datasource=’<%# ((DataRowView)Container.DataItem).Row.GetChildRows("myRelation") %>‘ > <ItemTemplate> <tr><td> <%# Eval("ItemName")%> </td> <td> <%# Eval("ItemDescription")%> </td> </tr> </ItemTemplate> </asp:Repeater> </itemtemplate> </asp:Repeater> </table>

 

Sure enough with this code you will run into a DataBinding: ‘System.Data.DataRow’ does not contain a property with the name x error. 

As a quick explanation for this error the following might suffice:

When the nested repeater binds to its datasource calling the GetChildRows command of the parent DataRowView.Row object the latter returns an array of DataRows (the “child rows”, an object of type DataRow[]) which each repeater Item will be bound to now. However, Eval with the above syntax will only bind to named fields of a DataView object that exposes a name property for each field. The DataRow returned by GetChildRows is merely a row in a table without the name properties so that each field can be accessed only with an indexer (DataRow["ItemName"]).

This is why you can either change the binding expressions above like so:

 

<td> <%# Eval("[\"ItemName\"]")%> </td> <td> <%# Eval("[\"ItemDescription\"]")%> </td>

or you can change the datasource to use the CreateChildView of the DataRowView directly like this:

<asp:Repeater ID=”childRepeater” runat=”server” datasource=’<%# ((DataRowView)Container.DataItem).CreateChildView(”myRelation”) %>’ >

and use old data binding syntax <%# Eval (”ItemName”) %> because now you have a DataView again (just like in the parentRepeater) which supports binding to the data field by name. Of course you have the option to do all the databinding in the code-behind file (usually the ItemDataBound event of each repeater) which gives you better debugging support than the approach above.

I find this “nested data” stuff overly complicated in ASP.NET, especially compared with how easy it is with Ruby on Rails. The plethora of objects which each behave differently is difficult to work with and the Repeater itself is limited in its built-in functionality and designer-support.

Sure enough I also ran into the

Compiler Error Message: CS0246: The type or namespace
name ‘DataRowView’ could not be found (are you missing a
using directive or an assembly reference?)

which IMHO is clearly a bug in ASP.NET as a reference to System.Data exists in the code-behind file that the .aspx web form inherits from. This issue can be fixed by either having an <%@ Import Namespace=”System.Data” %> tag in your aspx file or declaring DataRowView with the full namespace System.Data.DataRowView in the page each time.

For an in-depth view of the binding issues see this article. You might also find this post helpful.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Validating Windows Forms Text Input

Programming No Comments »

Unlike ASP.NET (which I’m more familiar with), Windows Forms don’t have any “Validation Controls”, so validating input has to be wired into the event model of your app. After some experimenting I found this procedure to work best for validating text box input:

1. Drop an ErrorProvider component onto your form. This component appears to have designer support when you drag it, however, it is not a control but a container-level component (like ImageList and ToolTip among others). The ErrorProvider component will display an error icon (ErrorProvider icon) next to the control that you specify programmatically during validation.

2. Handle the TextChanged Event
For TextBox validation, the preferred event is TextChanged as it lets you validate the contents of the control after they have been entered. Here’s an example:

 The field of view can’t be greater than a full circle (360 degrees):
image

 

 

 

 

 

If the user enters a letter, the error icon is displayed:

 

image

 

 

 

 

 

 

If the user enters a number too large, an error icon with a different message is displayed:

image

 

 

 

 

 

Here’s the event handler for the TextChanged event:

private void textBox1_TextChanged(object sender, EventArgs e) { if (!System.Text.RegularExpressions.Regex.IsMatch(textBox1.Text, @"^\d{1,3}$")) { errorProvider1.SetError(textBox1, "Please enter only up to three digits."); } else { if (float.Parse(textBox1.Text) > 360) { errorProvider1.SetError(textBox1, "FOV cannot be larger than 360°"); } else { errorProvider1.SetError(textBox1, ""); } } }

Regular expressions come to the fore here. The beginning of line (^) and end of line ($) characters in the pattern “^\d{1,3}$” are very important as otherwise the IsMatch function will return true as long as there is at least one decimal digit in the TextBox.Text.

Regular expression are cryptic which makes memorizing them hard. This article which accompanies the Expresso utility is great to refresh your memory. Hope it helps.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Synchronizing Local Data with a Remote Web Hosting Database

Programming No Comments »

Many webmasters of smaller web sites use the services of web hosting companies located in locations around the globe. Here in Thailand running your own web server is not feasible, as connections from the important markets of Europe, the Americas and even other parts of Asia might be too slow and unreliable. Using the services of a web hosting company usually involves running a local development database and an identical database running on the web hosting company’s servers.

To keep the contents in sync, it is desirable to have an easy-to-use system of uploading refreshed data to the remote database, ideally from the desk of every employee on the floor via an ASP.NET web app on the local intranet. There are several options available to achieve this:

Programming against SQL Server 2005 Integration Services (SSIS)

The successor of DTS is far more flexible and powerful than its predecessor, with great enhancements of the programming model in terms of extensibility and flexibility. How to call SSIS from C# is detailed in this article. However, SSIS are only installed with advanced versions (Standard upwards) of SQL Server and are not included with the free Express Edition nor the Workgroup edition (with the latter you apparently can open and save SSIS packages). I found this option not feasible, mainly because debugging is almost impossible and the Dts.Runtime.Package.Execute () method only returns very terse result code.

Using SQL

Of course you can issue INSERT queries that transfer your data to a remote database. If your remote server is a linked server you can simply issue a query like the following:

INSERT INTO [my.linked.server].myremotedb.user.mytable

SELECT * FROM localdb.user.mytable WHERE id = @ID

GO

However, if id is an identity column (as the name suggests), you’re out of luck as you have trouble with this query:

SET IDENTITY_INSERT [my.linked.server].myremotedb.user.mytable ON

This query issued to the linked server from your local db will usually fail in a hosting environment due to a lack of pertinent permissions.

An OPENROWSET ad-hoc connection won’t help you either because the KEEPIDENTITY table hint provided by an OPENROWSET query can only be used when inserting from a data file, while reading data from an OLEDB data source also might fail due to permission restraints.

SqlBulkCopy to the Rescue

ADO.NET 2.0 offers a fast and efficient way to transfer data to a remote database with the SqlBulkCopy class.

The following code illustrates this feature:

private void transferWidgetData(int widgetID) { //tables in the local and remote database are identical string[] myTables = { "widgets", "widgetDetails", "widgetPrice" }; string connectionStringLocal = ""; string connectionStringRemote = ""; using (SqlConnection conLocal = new SqlConnection(connectionStringLocal)) { foreach (string s in myTables) { //create the source command SqlCommand commandSourceData = new SqlCommand( "SELECT * " + "FROM " + s + " WHERE WidgetID = " + widgetID, conSource); SqlDataReader reader; //connection has to be re-opened for each datareader conSource.Open(); reader = commandSourceData.ExecuteReader(); using (SqlBulkCopy bcp = new SqlBulkCopy( connectionStringRemote, SqlBulkCopyOptions.KeepIdentity)) { bcp.DestinationTableName = "dbo." + s; try // Write from the source to the destination. { bcp.WriteToServer(reader); } catch (Exception ex) { //handle error here } finally { conSource.Close(); } } } } }

Note here the extremely useful SqlBulkCopyOptions.KeepIdentity hint which enables inserting identity values into the remote table. This code can easily be called from ASP.NET, enabling fast and flexible content management and synchronization with the remote database from your local intranet.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]
WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in