Tuesday, August 14, 2012

The Right Cred

I have a very long running update to a SQL database that I need to tame.  The problem is that the database to which this process writes is a production system, and the data just has to be there.  I need to make optimization changes and not have to worry about shutting down production if my efforts fail.

While the real answer is only downloading those records that have changed, I need to have a the database update fixed so we can use the data and so I can verify the correctness of the incremental approach when I finish.

I say all of that to say this.  I backed up the database using the
BACKUP DATABASE databasename TO DISK ='d:\sql\backup\databasename.bak'
I stored the backup on the network share, to free up the room on the server.  I attempted to restore the backup, to create a copy of the database, found that I couldn't do it.

It seems that the SQL Server services is running at local-only credentials.  The only way to restore the file is to copy the file to the local drives, or change the user that the service uses to a domain user.  You see, I assumed that since I was using the front end, it would be using my network credentials.  Not so.

So, I copied the file, and attempted to restore the file.  It didn't work.

Seems like I have to specify a new MDF file name for the restored file with a MOVE clause.

But, to use the MOVE clause, one must know what to move.  That's where this statement comes in.

RESTORE FILELISTONLY FROM DISK ='location of backup file' 
This command lists the logical and physical names of a database inside the backup file.

I combined all this knowledge to produce

RESTORE DATABASE newdatabasename
FROM DISK ='path to bak file'
WITH MOVE 'logical name of database' to 'path to the mdf file',
MOVE 'logical name of log file' to 'path to the ldf file' 


.

Friday, June 29, 2012

Text shadows

We should strive to learn everyday, especially in computers.  Just because you did something yesterday one way, doesn't mean that there isn't a better way to do it today.

Case in point is today and what I learned about text shadows.  Besides making text look more attractive, shadows can improve contrast and readability when using a text color that doesn't pop as well with the background as you would like.

 I was building a web page and wanted the colors of the headings to match the colors in the logo graphic.  The colors were blue and gold, and the gold header didn't pop against a egg-shell background.  I said "I need a drop shadow here."

In the past, I would have went to the GIMP (my favorite image editor.  It's free and very powerful.) and created a graphic with the text shadow.  But, I heard of a CSS property, text-shadow, that would do it. I tried it and it worked wonderfully.  Well, wonderfully in everything but IE.  But, since 54% of the desktop market runs IE, this will not do.

While nobody has ever accused Microsoft of being standards-compliant, they aren't slackers either.  There's usually a Microsoft-specific way of doing something when the compliant-specific way doesn't work.

And, of course, there is.  I found a really handy filter to use from Heygrady.com .  Please note:  it's not fast, so if your page is a bandwidth-hog, use the graphics method instead.

The code would be

h1{
text-shadow: 2px 2px 2px #000000;
filter: progid:DXImageTransform.Microsoft.Shadow(direction=135, strength=2,color=000000);}
The great thing about this is that everybody but IE ignores the filter property, and IE ignores the text-shadow property.



Friday, May 11, 2012

Concatenate stings with nulls

I was pulling a report in SQL Server, and getting strange results.
 SELECT FIRSTNAME  + ' ' +
                 MIDDLENAMEORINITIAL + ' ' +
                 LASTNAME as ContactName,
                 EMAILADDRESS
FROM aTable
The result set had ContactName as null whenever any of the three fields were null.  Any field concatenated with a null will be null.  The way to fix that is to wrap a ISNULL function around the field like this.

 SELECT  ISNULL(FIRSTNAME,'') + ' ' +
                 ISNULL(MIDDLENAMEORINITIAL,'') + ' ' +
                 ISNULL(LASTNAME,'') as ContactName,
                 EMAILADDRESSS
FROM aTable
This works with no problem!

Friday, September 02, 2011

Raising Our J-Score

I follow Joel Spolsky's Blog, which I find very useful and pithy.  Joel is a former Microsoft programmer, now CEO and programmer.  Joel published a blog way back in the Halcyon Days of 2000 entitled "The Joel Test: 12 Steps to Better Code"

So how do we stack up?


The Joel Test
1.  Do you use source control?
     Not yet.  We make file-system copies.  Our score:  0
2.  Can you make a build in one step?
     Depends.  My code is usually a yes, others, not a chance. Our score is a generous  .5
3.  Do you make daily builds?
     Not really.  Our score:  0
4.  Do you have a bug database?
     Nope  Our score: 0
5.  Do you fix bugs before writing new code?
     We try, but without a bug database, it's often hard to tell. I'm going to be very generous and say yes.  Our score 1.
6.  Do you have an up-to-date schedule?
      What's a schedule?  Our score:  0
7.  Do you have a spec?
     Real programmers don't need no stinkin' specs! That's a no, by the way.  Our score: 0
8.  Do programmers have quiet working conditions?
     What did you say?  It's too noisy in here!  Our score: 0
9   Do you use the best tools money can buy?
     Mostly.  Being a state agency, buying anything is challenging.   I'll say "yes".  Our score: 1
10 Do you have testers?
     Do programmers and users count?  No?  Then no.  The only thing harder than buying stuff is hiring people.  Our score:  0
11.  Do new candidates write code during their interview?
      Nope.  Our score: 0 
12.  Do you do hallway usability testing?
       No.  Our score:  0

Joel says "A score of 12 is perfect, 11 is tolerable, but 10 or lower and you've got serious problems. The truth is that most software organizations are running with a score of 2 or 3, and they need serious help, because companies like Microsoft run at 12 full-time. "

We scored a pathetic 2.5.  But there's hope!  I spend some time today investigating source control, and am confident that we will, kinda, sorta, start using it soon.  We're going with Mercurial , an open source distributed source control management tool.

If you've not looked at it, it is a command-line code repository.  If you are not using source control at all, look at this tutorialthis blog post, and this tutorial.  These sites will bring you up to speed.

Next in my sites, bug tracking!

That's Generic!

So you are creating a small config file and think "Gee, it would be nice to use the auto-serialization feature of  dot net"

So you wrap the serialization and deserialization routines as shared (static for you c# guys) functions, and throw a  _ in front of your class, and viola!

But, what if you are doing two, three, 48, 72 small serializable objects?  Ah, the power of object orientation!  Yes folks, object orientation makes this cake.  I created an abstract base class which contains the code I need to repeat for each small class.


Imports System.IO
Imports System.Xml.Serialization

Public Class AbstractSerialzationClass(Of t)
    Private Shared _ErrorOccured As Boolean = False
    Private Shared _ErrorText As String = ""
    Shared Function Deserialize(ByRef anObject As t, _
ByVal FileNameString As String) As Boolean

        _ErrorOccured = False
        If File.Exists(FileNameString) Then
            Try
                Dim aStreamReader As New StreamReader(FileNameString)
                Dim x As New XmlSerializer(anObject.GetType)
                anObject = CType(x.Deserialize(aStreamReader), t)
                aStreamReader.Close()
            Catch ex As Exception
                _ErrorOccured = True
                _ErrorText = "Unable to deserialze '" & FileNameString & "'." & ex.Message
            End Try
        Else
            _ErrorOccured = True
            _ErrorText = "XML File -'" & FileNameString & "' was not found"
        End If
        Return _ErrorOccured
    End Function
    Shared Sub Serialize(ByVal FileNameString As String, ByVal InObject As t)
        _ErrorOccured = False
        If File.Exists(FileNameString) Then
            If File.Exists(FileNameString & ".old") Then
                File.Delete(FileNameString & ".old")
            End If
            File.Copy(FileNameString, FileNameString & ".old")
            File.Delete(FileNameString)
        End If
        Try
            Dim aStreamWriter As New StreamWriter(FileNameString)
            Dim x As New XmlSerializer(InObject.GetType)
            x.Serialize(aStreamWriter, InObject)
            aStreamWriter.Close()
        Catch ex As Exception
            _ErrorText = "Unable to Serialze Annotation object to file named '" & FileNameString & "'.  " & ex.ToString
            _ErrorOccured = True
        End Try
    End Sub
    Public ReadOnly Property ErrorOccured() As Boolean
        Get
            Return _ErrorOccured
        End Get
    End Property
    Public ReadOnly Property ErrorText() As String
        Get
            Return _ErrorText
        End Get
    End Property
End Class


Now to use this in a class, all I've got to do is this

 Public Class foo
    Inherits AbstractSerialzationClass(Of foo)
end Class


Much neater!

Thursday, August 11, 2011

What's Different?

What's Different?

Remember the kids puzzles which asked you to spot the differences?  They were fun but also frustrating. I remember straring at a picture saying "WHAT'S DIFFERENT!"

How does this pertain to development? Well, we don't use an automated source code versioning system here at work (I know, we should). Instead, we make copies of each version of the program. So I will have a folder for each version of the code.  Sometimes, we accidentally use the wrong folder, and that makes my life resembles these puzzles.  I am puzzling  out what changed, when and why.

We have some command-line tools to compare folders, but that only reveals files that have changed.  We then have to load the files and do a file comparison with them.  Can we say tedious and time consuming?

That tedium was ended the day I found K-diff.  K-Diff is a really useful tool that can compare two folders and display all of the differences for you.  It highlights the files which have change, and double-clicking them brings up the files side-by-side for easy comparison.  It makes comparing differences easier and quicker.  It has made my life much easier.

You can find K-Diff here at http://kdiff3.sourceforge.net/  It's open source and is available for Windows, Linux, Unix, Mac and anything (in theory) that supports the qt libraries.

Wednesday, August 03, 2011