Tuesday, April 1, 2008

Thoughts On Altiris

The university has recently negotiated special pricing to purchase Altiris. Because of the need to support more automated maintenence of computers, and the pricing aspect, we decided to purchase it as well. Since we own the software, it is probably a decent idea to actually use it.

The first thing I did was download the "Client Management Suite" from Altiris' website. This suite contains what seems like an endless number of Altiris client packages and the Altiris Notification Server. The Notificiation Server can be installed seperately, but I chose the large package approach because we have licenses for many of the Altiris products.

It's probably important to note that the functionality in the Altiris products is very segregated. For example, Deployment Agent and the Sofware Delivery Agent address different issues even though their names sound extremely similar. This is the case for all of the Altiris clients. This can be extremely confusing, especially when there is overlap between agent functionality. For example, it is possible to deploy software through both of the following agents. Whip out your Venn Diagrams to understand the problem. This issue makes it difficult to understand the correct solution to use for a particular problem.

Additionally, don't install the Altiris Notification Server on a machine running anything else. The default deployment plays stampy the elephant on any .net applications you may already have running. The installation may not screw up other things if you have only ASP.NET 1.1 applications. However, if you have 2.0 applications this WILL NOT WORK. They register a ASAPI dll that doesn't seem to work with any 2.0 application. Most people install web applications to their own virtual directory and set the configuration at that level, but apperently the developers of Altiris don't know or care about doing this correctly.

Once the Notification Server is installed, the Altiris client needs to be distributed to the computers on the network. The client can do a number of different things, including installing other Altiris agents that do a myriad of other things.

Wednesday, March 26, 2008

hitachi jumper clip to 32 gigs

I had 2 250 gig Hitachi drives that were showing up in my BIOS and operating system as 33.8 gigabytes. A while back certain operating systems had a 32gig limit on the drive size that would be recognized by the operating system. To support this, drives were shipped with jumpers to allow them to be "clipped" at 32 gigs.

Looking at this objectively, it seems like a really silly thing to do. Why spend the extra money to buy a drive that you are going to clip back to 32 gigs. Also, I don't recall EVER having an operating system that couldn't support more than 32 gigs. The fact that it wasn't an issue back in 1999 when I purchased my first >32 gig drive (40 to be exact), I don't see why 9 years later drives are still being shipped with this fairly terrible hack. This is mostly justifying my lack of attention to the different jumper settings on the drive. It just seems pretty amazing that after working with computers heavily since 1994, this is the first time I've ever run across this problem.

Tuesday, March 18, 2008

SQL Counting Multiple Columns With Criteria

When doing counts, sometimes you want to count a record only when it meets a certain criteria. This can be annoying because the criteria generally needs to be posted in the "where" clause. This will give you only one count per sql query. If you want to have multiple counts per sql query you need to do sub-queries that can be costly.

select (Select count(FavoriteCandy) from mytable where FavoriteCandy='Tootsie Rolls') as TootsieCount, (Select count(FavoriteCandy) from mytable where FavoriteCandy='Baby Ruth') as BabyRuthCount

While this works it is really expensive. If multiple different counts over a large number of records is required, this method is not appropriate. While parusing the vast internets I ran into a different way of accomplishing the same task. I much prefer it to the former method.

select SUM(CASE when FavoriteCandy='Tootsie Rolls' THEN 1 END) as TootsieCount,SUM(CASE when FavoriteCandy='Baby Ruth' THEN 1 END) as BabyRuthCount from mytable

This treats the successful records as the number one and then sums the number of successes. When trying to count a number of different columns with criteria, this is definitly a cleaner and faster way to make the magic happen.

Thursday, December 6, 2007

Updating Key Fields in a DataGrid

When creating a GridView in Visual Studio, the default action for key fields is to disallow editing. While for the most part this is a good idea, there are some situations where this is not the desired action. I won't go over how to create a GridView tied to a DataSource because there are a plethorea of these articles already out there. This Tutorial will just explain how to make a non-updatable field in a GridView control tied to a DataSource updatable.

Defining the Problem

Lets say, for the sake of arguement, that I have a table of students GRE scores from applications. In this GRE scores table, I have the same student taking the test more than one time. Because there will be multiple records per student, I can't use their SSN or Student Identifier as the key. This means I will have to create a compound key of multiple fields in order to ensure uniqueness. Alternatively, I could just create an autonumber field. While easier, I don't believe this to be a very good technique. The autonumber doesn't have any context and doesn't relate to any other data.

The compound key I will use is the Students ID and the Date of the Test. This will ensure that each record will be unique. This brings up an issue when a date is entered incorrectly and needs to be updated in DataGrid. Because the date is part of the key, by default it will not be updateable in the DataGrid.

Looking at the SQL Code

The default Code for the update query is UPDATE [GRE_TABLE] set GREScore = @GREScore where [ID]=@ID and [TestDate]=@TestDate. The SQL code for the DataSource can be seen by highlighting the DataSource and clicking on UpdateQuery. The problem with this query is that it DOES NOT update the key fields. It only updates non-key fields, which in my example is the GREScore. The DataGrid will make the Key Fields Read only to signal to the developer that these fields are not updatable.

Why is this the Default Action?

The issue with updating a key field is that the value of the key field changes. Why is this a problem? Well, the key field is used to identify a row. If you attempt to identify the row with the new value, well now, it just won't be found now will it. This is a tricky thing to understand if you don't know sql very well, so an example should help.

In the SQL example above, our update command is updating GREScore where ID=ID and TestDate=TestDate. Lets say that our ID is 5 for our student and that their test date was 10/20/2007. Now lets assume that our test date was incorrect. The actual test date is 10/21/2007 and we want to change it. In order to make the swap, it is necessary to find the record with the first date, and update it with the second date. In pseudo-code, we would update GREScore and TestDate where ID=ID and TestDate=OriginalTestDate. Or, Update GREScore='510' and TestDate=10/21/2007 where Id=5 and TestDate=10/20/2007. If it was attempted to update the TestDate with the current value, the update would try to find the record 10/21/2007 which isn't in the table and just quietly not update anything just like it was asked.

Fundimentally, the problem is that we need both the OLD TestDate value and the NEW TestDate value to update the Grid, but by default we are only given the current.

Getting the Original and New Values

Now that the problem is understood, that by default there is only access to the New Value, let's change the DataSource so that we have access to both the old and new values.

The magic that is necessary to do this is called the OldValuesParameterFormatString property of the DataSource. This lets the programmer define the naming convention for the old values of the Grid before they were modified. In most examples, people will set this parameter to Original_{0}. Doing this creates just what we wanted above! Now there will be access to both the Old value of DateTime and the New value of DateTime. In the SQL code, to access the Old value of DateTime the convention @Original_DateTime will give this value.


Changing the SQL Code

Lets revisit the SQL code and make the changes we need to update a key field in our DataGrid. The code before was UPDATE [GRE_TABLE] set GREScore = @GREScore where [ID]=@ID and [TestDate]=@TestDate. After the changes we've made, lets create the code to update the TestDate key field. The New code should be UPDATE [GRE_TABLE] set [GREScore] = @GREScore, [TestDate]=@TestDate WHERE [ID]=@Original_ID and [TestDate]=@Original_TestDate.

Notice that we need to use @Original_ values to find the old record so that we can update it with the values in the Grid. This is sort of tricky because the old ID needs to be changed to Original_ID which implies that before changing the OldValueParameterFormatString ID was populated with the original value. Now that the property is set ID is empty because it isn't in our grid and only the original value is populated. If you are getting a scalar variable not defined, this is because you are trying to access the new value of ID that doesn't exist now.

Cleaning Up and Going Home

Now that the key field in the DataSource can be updated, simply change the column property of the grid to allow edits.

Tuesday, December 4, 2007

Moving a Subversion Repository

To move a repository, first you need to create a dump of the old repository. This can be done with the command svnadmin dump /Path/to/Repository >Repository-name.dmp. This dump can be loaded by doing the svnadmin load Repository-name <repository-name.dmp. It's just that easy.

Setting Up Subversion Server on Windows

Getting subversion working on windows isn't that bad of a task. I've been using it to track Visual Studio projects here at work. While it isn't too hard to do, it can be confusing the first time around. I also end up forgettting commands so putting it in one spot is probably a good idea. So, here is my attempt at making a tutorial, as much for me later as for you now.


Things You'll Need



  1. Subversion Windows Binary Package. The version I'm installing is 1.4.3. http://subversion.tigris.org/project_packages.html

  2. A way to manage your repository. I use tortoisesvn on windows. This is the client piece to the equation. http://tortoisesvn.net/



Create a Repository


Install the Subversion binary package. This is extremely straight forward and only requires clicking next and continue until it's complete. It will install to documents and settings\subversion.

Once Subversion is installed a location for the repository needs to be created. I normally pick some place that gets backed up by a regular server backup. It my case it is going to be F:\Subversion. Just create an empty folder to hold our projects.

This is a matter of preference, but I like to set up my projects under the main root folder and manage each of them seperately. This means I need to create logins and passwords under each repo, but I like how it is split up. An example is that my projects will be f:\Subversion\MyProject1. So, create a folder for this project and we'll get to setting up the repository.

To create a project skeleton, I used the command svnadmin create "F:\Subversion\MyProject1". This will create a bunch of folders and files in the MyProject1 Directory.

Set Security

Now the security for the repository needs to be set. It seems like there are a lot of options to configure security, but I'm going to use the default file based security. To set this up, I opened svnserve.conf in the conf directory of the project and uncommented anon-access = read and auth-access = write. I also changed anon-access from read to none because I don't want to allow anonymous access to my repository. It is also necessary to uncomment password-db=passwd.

Save the file and open up passwd file and put in the username and password that you will use to access the repository.

Test The Repository

Now test the repository by running the command svnserve --daemon --root "F:\Subversion" from the terminal. This runs the subversion daemon and serves up all of the projects under F:\Subversion. Using tortoiseSVN, connect to svn://hostname/MyProject1. This can be done by right clicking on a folder and going to the Repo browser. If the connection works, you should be ready to run Subversion as a service and then start adding content to your repository.


Registering Subversion as a Service


Now that we have subversion set up, lets register it as a service on windows. There are a few ways of doing this, but I used the sc command that is packaged with Subversion. I opened a command prompt and typed this in to create a service C:\>sc create svnserve binpath= "C:\Program Files\Subversion\bin\svnserve.exe --service --root F:\Subversion" displayname= "Subversion" depend= tcpip start= auto obj= "NT AUTHORITY\LocalService". This creates a Subversion service that is serving F:\Subversion and starts automatically. It also runs using the "NT Authority\LocalService" account which is recommended. You may need to start the service by going into the windows services and starting the Subversion Server.

Adding Files to the Repository

To add files to the repository, right click on the folder that contains the source and click import. Then give it the svn://hostname/MyProject1. This will upload your files into the repository and set the revision to 1.

Getting to work

You can now right click on any folder with Tortoise and checkout the files to that folder to start working on them.

Helpful Links

I used the following links to help me install Subversion. Thanks to the people that wrote them and hopefully they are helpful to you as well.

Running Subversion as a service.

http://tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-serversetup-svnserve.html

Installing and Configuring the Server

http://www.excastle.com/blog/archive/2005/05/31/1048.aspx