SQL Server: Show all the FOREIGN KEYS that reference a TABLE

November 5, 2009

For SQL 2005+


DECLARE
     @tableName nvarchar(MAX)
SET
    @tableName = 'tableName' -- (1)

SELECT DISTINCT
     ccu.table_name,
     ccu.constraint_name
FROM
     INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
INNER JOIN
     INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
          ON rc.unique_constraint_name = tc.constraint_name
INNER JOIN
     INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu
          ON ccu.constraint_name = rc.constraint_name
WHERE
     tc.table_name = @tableName

Notes:

  • Change line (1) to specify the table name.

 


SQL Server: Show all the PRIMARY KEYS for a TABLE

November 5, 2009

For SQL Server 2005 + 


DECLARE

     @tableName nvarchar(MAX)
SET

     @tableName = 'tableName' -- (1)

SELECT

      tc.TABLE_NAME,

      tc.CONSTRAINT_NAME,

      kcu.COLUMN_NAME,

      kcu.ORDINAL_POSITION

FROM

      INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc

INNER JOIN

      INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu

      ON tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME

WHERE

      tc.CONSTRAINT_TYPE = 'PRIMARY KEY'

      AND

      tc.TABLE_NAME = @tableName OR @tableName IS NULL

ORDER BY

      tc.TABLE_NAME,

      kcu.ORDINAL_POSITION

Notes:

  • Change line (1) to specify the table name. Removing this line will list PRIMARY KEYS for all TABLES.

VB.Net: Determine if an Object or Class Implements and Interface

June 29, 2009

The Problem

You want to know if a class called MyClass implements interface IMyInterface, or the object myObject inplements interface IMyInterface.

Unfortunately, you can’t do:

If MyClass Is IMyInterface Then

The Solution

It isn’t exactly intuitive, but for a class you can do this:

If GetType(IMyInterface).IsAssignableFrom(MyClass) Then
    ' Do something interesting, e.g.
    CType(MyObject, IMyInterface).MethodOnIMyInterface()
End If

Or for an object:

 If GetType(IMyInterface).IsAssignableFrom(MyObject.GetType) Then
    ' Do something interesting, e.g.
    CType(MyObject, IMyInterface).MethodOnIMyInterface()
End If

UltraWebTab: Switch to Tab on Validation Error

June 24, 2009

The Problem


I have an ASP.Net form that contains a set of tabs hosted inside an Infragistics UltraWebTab control. Each tab contains a number of fields that have validation. Sometimes, when the user submits the form, a validation error occurs. When this happens, I want the user to be able to correct the error with a minimum of fuss – I want the tab containing the error to be automatically selected, and the control with the error to be given the focus.

The Solution

The following code causes the first tab that contains an error to be selected when the form submits:

// These scripts are responsible for handling validation error messages in the tabs.
// If there are any errors on the page, they switch to the tab containing the first
// error and ensure that the control with the error is focused.

 function preValidate() {
  // For each of the validators on the page...
  var i;
  for (i = 0; i < Page_Validators.length; i++) {
   // Perform the validation.
   ValidatorValidate(Page_Validators[i]);

   // If invalid data is found...
   if (!Page_Validators[i].isvalid) {

    // Get the control that failed validation.
    var badControl = document.getElementById(Page_Validators[i].controltovalidate);

    // Focus it.
    focusInvalid(badControl);

    // Stop processing validation.
    return;

   }
  } // Next validator.

  // The page is valid.

 }

 function focusInvalid(badControl) {

  // Get the index of the tab that contains this control.
  var tabIndexToFocus = getContainingTabIndex(badControl);
  if (tabIndexToFocus > -1) {
   // Switch to the tab that contains the validation error.
   var ultraTab = igtab_getTabById('<%=UltraWebTab1.ClientID %>');
   ultraTab.setSelectedIndex(tabIndexToFocus);

   // Focus the control and exit.
   badControl.focus();
  }
 }

 function getContainingTabIndex(targetControl) {

  var ultraTab = igtab_getTabById('<%=UltraWebTab1.ClientID %>');

  // Get a reference to the tabs.
  var tabs = ultraTab.Tabs;

  // Start with the control that failed to validate.
  var testControl = targetControl;

  // While we have not got to the top of the control heirarchy...
  while (targetControl != null) {
   // Walk up the DOM to seek out the tab panel that contains the target control.
   testControl = testControl.parentNode;

   // For each of the tab panels...
   var tabIndex;
   for (tabIndex = 0; tabIndex < tabs.length; tabIndex++) {
    if (tabs[tabIndex].elemDiv == testControl) {
     return tabIndex;
    }
   } // Next index.

  } // Wend.

  // The control is not contained in a tab panel.
  return -1;
 }       

To run the script, attatch it to the OnClientClick event of the button that submits the form:

<asp:Button ID="btnSubmit" runat="server" Text="Submit" OnClick="btnEdit_Click" OnClientClick="preValidate();" />

Note that validation of each control will happen twice if the form is valid; once for the code above and then once because that’s how ASP.Net works. This doesn’t normally matter with the standard ASP.Net controls, but it might be an issue with badly-written custom validation controls. You have been warned!


MIDP 1.0 fillTriangle Method

June 1, 2009

One of the (many) limitations of MIDP 1.0 is that it lacks the fillTriangle that is present in MIDP 2.0. Below is a replacement method that works on MIDP 1.0 devices. It is based on notes published by Michal Wronski.

Michal’s algorithm depends on floating-point math – also unavailable in MIDP 1.0. With a little refactoring I was able to create an integer-only approximation. Sadly, rounding errors mean that my routine isn’t pixel perfect. An alternative that would give more accurate results would be to use some kind of fixed-point library. Despite its shortcomings, however, my method is good enough for many practical purposes (including my own).

    protected void drawHorizontalLine(int x1, int x2, int y)
    {
        graphics.drawLine(x1, y, x2, y);
    }

    protected void fillTriangle(int ax, int ay, int bx, int by, int cx, int cy)
    {
        // http://www.geocities.com/wronski12/3d_tutor/tri_fillers.html

        // Sort the points so that ay <= by <= cy
        int temp;
        if (ay > by)
        {
            temp = ax;
            ax = bx;
            bx = temp;
            temp = ay;
            ay = by;
            by = temp;
        }
        if (by > cy)
        {
            temp = bx;
            bx = cx;
            cx = temp;
            temp = by;
            by = cy;
            cy = temp;
        }
        if (ay > by)
        {
            temp = ax;
            ax = bx;
            bx = temp;
            temp = ay;
            ay = by;
            by = temp;
        }       

        // Calc the deltas for each edge.
        int ab_num;
        int ab_den;
        if (by - ay > 0)
        {
            ab_num = (bx - ax);
            ab_den = (by - ay);
        }
        else
        {
            ab_num = (bx - ax);
            ab_den = 1;
        }

        int ac_num;
        int ac_den;
        if (cy - ay > 0)
        {
            ac_num = (cx - ax);
            ac_den = (cy - ay);
        }
        else
        {
            ac_num = 0;
            ac_den = 1;
        }

        int bc_num;
        int bc_den;
        if (cy - by > 0)
        {
            bc_num = (cx - bx);
            bc_den = (cy - by);
        }
        else
        {
            bc_num = 0;
            bc_den = 1;
        }

        // The start and end of each line.
        int sx;
        int ex;

        // The heights of the two components of the triangle.
        int h1 = by - ay;
        int h2 = cy - by;

        // If a is to the left of b...
        if (ax < bx)
        {
            // For each row of the top component...
            for (int y = 0; y < h1; y++)
            {
                sx = ax + ac_num * y / ac_den;
                ex = ax + ab_num * y / ab_den;
                drawHorizontalLine(sx, ex, ay + y);
            }
            // For each row of the bottom component...
            for (int y = 0; y < h2; y++)
            {
                int y2 = h1 + y;
                sx = ax + ac_num * y2 / ac_den;
                ex = bx + bc_num * y / bc_den;
                drawHorizontalLine(sx, ex, by + y);
            }
        }
        else
        {
            // For each row of the bottom component...
            for (int y = 0; y < h1; y++)
            {
                sx = ax + ab_num * y / ab_den;
                ex = ax + ac_num * y / ac_den;
                drawHorizontalLine(sx, ex, ay + y);
            }
            // For each row of the bottom component...
            for (int y = 0; y < h2; y++)
            {
                int y2 = h1 + y;
                sx = bx + bc_num * y / bc_den;
                ex = ax + ac_num * y2 / ac_den;
                drawHorizontalLine(sx, ex, by + y);
            }
        }
    }

I release this code into the public domain. You can use it as you please.


Source Code Formatting in WordPress

June 1, 2009

Finally, I have found the document that describes how this can be done:

http://support.wordpress.com/code/


BBC Micro Game Cheats

May 27, 2009

One of my interests as a teenager was hacking games to make them easier. I recently came across some notes I made on some of the cheats that I found.300px-bbc_micro.jpeg

I appologise for any errors in the information below. The cheats have been extracted from scrawled notes I made back in the 80s, and not tested recently.

Mr Wimpy

The number of lives is set here:

&5DC9: LDA #&04
&59CB: STA &630

The number of lives is decreased here:

&4442: DEC &630

Jet Pack

The start address for running the code is:

&5900

The number of lives is set here:

&307A: LDA #5
&307C: STA &88

The number of baddies on screen 2 is set here:

&344B : LDA #5

Castle Quest

The start address for running the code is:

&4340

The number of lives is set here:

&5996: LDA #?
&5998: STA &46

The number of lives is decreased here:

&58E9: DEC &46 (or is this &58ED)?

To eliminate all monsters from the game, remove the JSR and destination address from:

&4523: JSR xxxx

and replace with:

&4523: NOP NOP NOP

Planetoid

The start address for running the code is:

&1100

The initial number of lives / smart bombs is set here:

&276A: LDA #3 (Note: this value may be BCD).

Jest Set Willy (?)

Partial disassembly:

&5573: LDA #&68 - Initial Y coordinate
&5575: STA &A24
&5578: LDA #&A8 - Initial X coordinate
&557A: STA &A1B
&557D: LDA #&12 - Initial room
&557F: STA &55

Demon Decorator

To list the code:

*LOAD at &0E00

RENUMBER and remove lines 20, 100, 330, 850, 1310, 50

Cybertron Mission

For infinite lives:

  1. Load part 1
  2. Find the line that starts “*RUN…” and change to “*LOAD…”.
  3. Run the program.
  4. Whern part 2 has loaded, type ?&261E = &EA<Return>
  5. Call &4F80

Great Programming Books: 2008

December 10, 2008

Last year, I made a list of Great Programming books. Here is an update to that list.

I have read and highly recommend the following:

These are often recommended by people who have read the above:

  • Alan Cooper, “The Inmates Are Running the Asylum: Why High Tech Products Drive Us Crazy and How to Restore the Sanity
  • Tom DeMarco and Timothy Lister , “Peopleware – Productive Projects and Teams
  • Martin Fowler, “Patterns of Enterprise Architecture
  • Eric Freeman, Elisabeth Freeman, Kathy Sierra, Bert Bates, “Head First Design Patterns
  • Erich Gamma et al, “Design Patterns: Elements of Reusable Object-Oriented Software
  • Andrew Hunt and David Thomas , “The Pragmatic Programmer: From Journeyman to Master
  • Bertrand  Meyer, “Object-oriented Software Construction

Other people’s ideas about great programming books:


More .Net Cheat Sheets

December 1, 2008

I have linked a few before.

There are more here:


Quote: Programmers are Romantics

December 1, 2008

Programmers are romantics. We’re lovers not fighters.

Why, developers are widely regarded as being the sexiest creatures on the planet. Our beauty causes people in other professions to go blind. We are love. We are truth. We are sex at a keyboard.

– Peter O’Hanlon, Code Project.