2007/05/30

KeePassX looks ugly; making it look good again

If KeePassX (or other Qt application) looks really awful on your machine, the problem is probably the GUI Style chosen for Qt applications.

For quite a long time I couldn't find a way to change it, until I read this howto. I installed the qt4-qtconfig package and used the Qt Configuration tool (run qtconfig) to change the GUI Style to Plastique. You can see the results below.

Before
Ugly KeePassX

After
Nice KeePassX

2007/05/28

Neostrada ADSL + Linux + Siemens SpeedStream 4100 modem

If you have a Neostrada ADSL connection and a Siemens SpeedStream 4100 modem, it is really easy to configure it on Linux. You only have to:
  1. edit the /etc/network/interfaces file and configure the card connected to the modem (you need to set the IP address, the gateway, the netmask and the broadcast address - your provider should give you all this data)
  2. execute /etc/init.d/networking restart
I am by no means a network guru and I cannot exactly explain why it has to be done like this, but my guess is that the modem handles all the PPPoE stuff, so no PPPoE client (like RP-PPPoE) is necessary.

2007/05/16

A SQL CLR user-defined aggregate - notes on creating and debugging

At the end of this post you will find my very first attempt to use one of the new features of SQL Server 2005 - CLR integration. It is a CLR user-defined aggregate that produces a comma-separated (comma plus space to be precise) list of values.
Column1
--------
aaa
bbb       -->   aaa, bbb, ccc
ccc
My code is a modified version of an example that I found here.

Global variables

You may expect (at least I did) that if you have a global variable (e.g. intermediateResult in my example) and you assign it a value in the Init method then you will be able to use this value in the Terminate method. Well, that's not true.

If you need to use a value of some variable in the Terminate method, you have to serialize it in the Write method (to save the needed value) and then deserialize it in the Read method and assign to some variable (to restore the needed value).

You can of course save and restore more than one variable - use some kind of serializable object to store the values.

Debugging

There is an MSDN article that explains exactly how to debug a CLR user-defined aggregate - Walkthrough: Debugging a SQL CLR User-Defined Aggregate - nonetheless, I encountered one problem.

I started with a solution that contained two projects - one project contained the aggregate code and the other was for a SQL test script. It is possible to perform debugging in such configuration (I managed to do it, although I am not sure how), but it is a better idea to have a single SQL Server project with both the aggregate code and SQL test scripts. This is what the IDE expects, so following this advice can spare you lots of hassle.

For example, MSDN says that to debug a CLR user-defined aggregate you need to enable CLR Debugging, but it doesn't say that Application Debugging must also be enabled.

Application Debugging option

When I worked with a single project, Visual Studio enabled this option automatically when needed, while with the two-project solution I had to do it myself.
using System;
using System.Data;
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.IO;
using System.Text;

[Serializable()]
[SqlUserDefinedAggregate(
    Format.UserDefined,
    IsInvariantToNulls=true,
    IsInvariantToDuplicates=false,
    IsInvariantToOrder=false,
    MaxByteSize=8000)]
public class Concat : IBinarySerialize
{
    #region Private fields
    private string separator;
    private StringBuilder intermediateResult;
    #endregion

    #region IBinarySerialize members
    public void Read(BinaryReader r)
    {
        this.intermediateResult = new StringBuilder(r.ReadString());
    }

    public void Write(BinaryWriter w)
    {
        w.Write(this.intermediateResult.ToString());
    }
    #endregion

    #region Aggregation contract methods
    public void Init()
    {
        this.separator = ", ";
        this.intermediateResult = new StringBuilder();
    }

    public void Accumulate(SqlString pValue)
    {
        if (pValue.IsNull)
        {
            return;
        }

        if (this.intermediateResult.Length > 0)
        {
            this.intermediateResult.Append(this.separator);
        }
        this.intermediateResult.Append(pValue.Value);
    }

    public void Merge(Concat pOtherAggregate)
    {
        this.intermediateResult.Append(pOtherAggregate.intermediateResult);
    }

    public SqlString Terminate()
    {
        return this.intermediateResult.ToString();
    }
    #endregion
}

2007/05/14

How to improve sub-pixel font rendering for Feisty (from Ubuntu Guide)

The fonts look way better out-of-the-box in Ubuntu 7.04 than they used to in previous versions (I wrote about this before - 1, 2), but they can still be improved.

How to improve sub-pixel font rendering for Feisty
This will dramatically improve the appearance of fonts with respect to the default Ubuntu install. The patched libraries are built against Freetype 2.3.x (not currently in feisty) and include David Turner's sub-pixel rendering patches.

In my opinion, the results are really impressive.

2007/05/12

Regular expressions are easy! You only need Regulazy

I think that this tool is really, really great. Regulazy is an absolute (if you know me, you know that I don't get overexcited like this very often ;) must-have for anybody who needs to create regular expressions, but is not a regex guru.
Regulazy is a visual Regex Creation tool for beginners.
It contains an easy "point and click" user interface, and allows creating regular expressions for simple searches almost instantly without requiring Regex syntax knowledge from the end user!
And if you need a more advanced and powerful tool, check out The Regulator. I have used it a few years ago and found it great, too.

2007/05/08

'Alter table failed because unique column IDs have been exhausted for table MY_TABLE' error

Below you'll find a excerpts from my conversation with Peter Yang from Microsoft in microsoft.private.directaccess.sqlserver newsgroup.

Me:
When I try to add a column to MY_TABLE, the ALTER TABLE statement fails with the following error:

Alter table failed because unique column IDs have been exhausted for table 'MY_TABLE'.

1. Can you please explain this exactly means?
2. What is the 'column ID'? (I suppose it is some column in some system table)
3. Is there any way to solve this problem apart from dropping and re-creating the table?
Peter Yang:
Since column id is not reused and the server also defines the maximum number of column id (MAXCOLID == 32000), then trying to alter table add column, alter table drop column until beyond 32000 iteration will be failed. You shall see the error message you encounter under the situation.

For example, using the following script shall reproduce the problem:
CREATE TABLE T1 (C int, C0 varchar)
GO

CREATE CLUSTERED INDEX IDX1 ON T1(C)
GO

DECLARE @i int
SET @i = 1
WHILE @i <= 32770
BEGIN
IF @i % 2 = 1
BEGIN
ALTER TABLE T1 ADD C1 varchar   
ALTER TABLE T1 DROP COLUMN C0    
END    
ELSE   
BEGIN   
ALTER TABLE T1 ADD C0 varchar   
ALTER TABLE T1 DROP COLUMN C1  
END  
SET @i = @i + 1
END 
GO 

DROP TABLE T1
GO
To work around the issue, you may need to create a new table with the columns you want other than alter the table since it has reached maximum ids of the server.
Me:
I just to want to make sure that re-creating the entire table is the only way to solve this problem. There is no way to reset the column id value, is there?
Peter Yang:
Thank you for your reply. Based on my research, there is no method to reset columnID value for a table and columnIds are not reused. This is by design behavior and hard coded right now.

UPDATE:

I am not the only one who encountered this problem. A guy from work showed how to determine the maximum used COLUMN_ID for a chosen table.
-- SQL Server 2000
SELECT 
name AS TABLE_NAME
, info AS MAX_COLUMN_ID_USED
FROM sysobjects
WHERE id = OBJECT_ID('put_the_table_name_here')

-- SQL Server 2005
SELECT 
name AS TABLE_NAME
, max_column_id_used AS MAX_COLUMN_ID_USED
FROM sys.tables
WHERE object_id = OBJECT_ID('put_the_table_name_here')

UPDATE 2:

My suggestion submitted to Microsoft - if you have this problem too, rate it!

2007/05/03

Album Cover Art Downloader does not start

Today I've run into my first problem caused by upgrading Ubuntu to version 7.04 - Album Cover Art Downloader (version 1.6.0) stopped working.

If you try to run Album Cover Art Downloader (by typing albumart-qt in the console) and get the following error:
Traceback (most recent call last):
File "/usr/bin/albumart-qt", line 145, in 
sys.exit(runGui())
File "/usr/bin/albumart-qt", line 77, in runGui
import albumart_dialog
File "/usr/lib/albumart/albumart_dialog.py", line 32, in 
from pixmap import getPixmapForPath
File "/usr/lib/albumart/pixmap.py", line 4, in 
import albumart_images
File "/usr/lib/albumart/albumart_images.py", line 6
SyntaxError: Non-ASCII character '\xa0' in file 
/usr/lib/albumart/albumart_images.py on line 6, but no encoding declared; 
see http://www.python.org/peps/pep-0263.html for details
open the /usr/lib/albumart/albumart_images.py and in the first or second line in the file add:
# coding: latin-1