Monday, December 7, 2009

KSW Forms

This is a truly amazing and beautiful demo of many KSW form by master Sung Jin Suh.



If you're trying to perfect your Ki Cho Hyung, pay close attention starting @ 2:55.

And while you're at it enjoy the impossible dream.


Another KSW demo is here (requires facebook login)
http://www.facebook.com/video/video.php?v=1153365839906&sfrm

Friday, November 13, 2009

Stranges Behavior with AutoCompleteExtender

Two odd behaviors with AutoCompleteExtenders I wanted to jot down before I forget.
If have want to set the focus on the textbox bound to the AutoCompleteExtender using JavaScript code (on pageLoad for example), the AutoCompleteExtender won't work

here's more on this and a solution
http://forums.asp.net/t/1397904.aspx

and here http://forums.asp.net/t/1220054.aspx

The other odd behavior is I think when we have a textbox with AutoCompleteExtender, the page tries to find the first input element with type = "submit" and selects such that if you hit enter that button will be clicked. I am not 100% sure, but I ran into this today.

I got around this by adding UseSubmitBehavior="false" property to all the buttons in the page. Doing so cause a problem, because some buttons had OnClientClick property populated and when their UseSubmitBehavior property set to false, they stopped submitting the form. The work around here is to submit the form using JavaScript code for example

asp:Button id="btnNew" runat="server" UseSubmitBehavior="false"
OnClientClick="if(validateForm()) this.form.submit();"

Thursday, November 12, 2009

Browser Programming

Using the new programming language Go http://golang.org/ from Google, it will be possible to run Go programs directly in browsers like Chrome. http://news.cnet.com/8301-30685_3-10395355-264.html?part=rss&subj=news&tag=2547-1_3-0-5

The question is how will web developers adopt this new approach?

Monday, November 2, 2009

Script to Enable/Disable All Foreign Keys

To generate SQL statements which will disable all foreign key constraints in a database, you can use this script

select 'ALTER TABLE [' + s.name + '].[' + t.name + '] NOCHECK CONSTRAINT [' + fk.name +'];'
as script
from sys.foreign_keys fk inner join sys.tables t on fk.parent_object_id = t.object_id
inner join sys.schemas s on t.schema_id = s.schema_id

To enable foreign key the NOCKECK keyword needs to be changed to CHECK

If data was inserted when tables foreign keys were disabled and would like to check integrity,
DBCC CHECKCONSTRAINTS('TABLE_NAME') [WITH ALL_CONSTRAINTS] can be used
the optional WITH ALL_CONSTRAINT is used to include all constraints even the ones that are disabled even the ones

Here is a capture script from sql profile to see all foreign keys and their columns

SELECT
SCHEMA_NAME(tbl.schema_id) AS [Table_Schema],
tbl.name AS [Table_Name],
cstr.name AS [ForeignKey_Name],
fk.constraint_column_id AS [ID],
cfk.name AS [Name],
crk.name AS [ReferencedColumn]
FROM
sys.tables AS tbl
INNER JOIN sys.foreign_keys AS cstr ON cstr.parent_object_id=tbl.object_id
INNER JOIN sys.foreign_key_columns AS fk ON fk.constraint_object_id=cstr.object_id
INNER JOIN sys.columns AS cfk ON fk.parent_column_id = cfk.column_id and fk.parent_object_id = cfk.object_id
INNER JOIN sys.columns AS crk ON fk.referenced_column_id = crk.column_id and fk.referenced_object_id = crk.object_id
ORDER BY
[Table_Schema] ASC,[Table_Name] ASC,[ForeignKey_Name] ASC,[ID] ASC

Friday, October 2, 2009

Shrink Databases using sp_MSForEachDB

Using undocumented stored procedure sp_MSForEachDB and DBCC SHRINKDATABASE command you can shrink all databases on an SQL Server in one line of code

exec sp_MSForEachDB 'if ''?'' not in (select name from sys.databases where is_read_only = 1) DBCC SHRINKDATABASE([?]) '

You may need to add additional checks [skip offline dbs for example]. Test on SQL Server 2005.

Wednesday, May 20, 2009

T-SQL Script to Generate SHRINKFILE statements for all DBs

This a t-sql script I use to generate DBCC SHRINKFILE statements for all databases on a SQL Server 2005/2008. Microsoft recommends that you change the recovery model to simple shrink the file and change back to full if the recovery model is full to begin with. You cannot shrink readonly dbs (or offile dbs obviously)

The script is provided AS IS.

use master;
GO
create procedure [dbo].[udp_genShrinkStatements] as begin
declare @sql nvarchar(max);
declare @filename varchar(256);
declare @dbid int;
declare @dbname varchar(256);
declare @recoveryModel int; -- 3 simple; 1 full
declare dbcursor cursor for SELECT     database_id,[name], recovery_model --, recovery_model_desc
FROM         sys.databases
WHERE     (database_id > 4) AND (is_read_only = 0) and (state = 0) --skip system, readonly and offile dbs
ORDER BY   [name]
open dbcursor;
set @sql = '';
fetch next from dbcursor into @dbid,@dbname,@recoveryModel;
while @@FETCH_STATUS = 0
begin
declare filecursor cursor for SELECT [name] from sys.sysaltfiles where dbid = @dbid;
open filecursor;
select @dbname = '['+@dbname+']';
--select @sql = @sql + @dbname;
-- print '--'+@dbname;
--select @sql = @sql + '--';
-- print 'USE ' + @dbname +';';
select @sql = @sql + 'USE ' + @dbname +';' ;
-- print 'GO';
--select @sql = @sql + ' GO ';
if @recoveryModel = 1
begin
-- print 'ALTER DATABASE '+@dbname +' SET RECOVERY SIMPLE WITH NO_WAIT;';
select @sql = @sql + 'ALTER DATABASE '+@dbname +' SET RECOVERY SIMPLE WITH NO_WAIT;';
end
fetch next from filecursor into @filename
while @@FETCH_STATUS = 0
begin
-- print 'DBCC SHRINKFILE('''+ @filename +''');';
select @sql = @sql + 'DBCC SHRINKFILE('''+ @filename +''');';
fetch next from filecursor into @filename
end
close filecursor
deallocate filecursor
if @recoveryModel = 1
begin
-- print 'ALTER DATABASE '+@dbname +' SET RECOVERY FULL WITH NO_WAIT;';
select @sql = @sql + 'ALTER DATABASE '+@dbname +' SET RECOVERY FULL WITH NO_WAIT;';
end
-- print '---------------';
--select @sql = @sql + '---------------';
fetch next from dbcursor into @dbid,@dbname,@recoveryModel;
end
close dbcursor;
deallocate dbcursor;
--exec sp_executesql @stmt = @sql;
SELECT @sql;
end

Tuesday, March 10, 2009

Report Builder 2.0 & Reporting Services 2008

We're still on reporting services 2005 but I've playing with Report Builder 2.0 in which you can see some of the features of Reporting Services 2008 such as the long-awaited control tablix. Very Nice! you can download it from here [http://www.microsoft.com/downloads/details.aspx?familyid=9f783224-9871-4eea-b1d5-f3140a253db6&displaylang=en] The builder looks really cool and the look-and-feel of Office 2007 and many more improvements of the VS Designer for RS 2005. 

Of of most annoying bugs in 2005 was that when you make a change to a query in the report DataSet+ and save the report using CTRL+S (or click save icon), the DataTime parameters were converted to Strings. But so far I haven't seen this happening in RB 2008.

One way I worked around the bug I mentioned (DateTime converted to Strings) is by building the query after making the changes and before CTRL+S  ( or saving).

Other welcomed additions to Reporting Services 2008 are the better charting capabilities and the Gauge controls.

Tuesday, March 3, 2009

T-SQL: A Set-Oriented Language + Ranking Functions

The other day I had a query that invloved several tables and complex logic to a certain degree. The initial query involved using user-defined functions and the such and it took roughly 12 minutes to run which was not acceptable. After a little bit of tweeking and thinking of sets and not procedural logic I managed to the query to run in under 10 seconds for the same amount of data. Thanks partially to t-sql ranking functions [ http://msdn.microsoft.com/en-us/library/ms189798.aspx#]

Dense_Rank was especially useful. Unlike Rank(), Dense_Rank() does not leaves gap in the sequence of numbers desginating ranks.

Sunday, February 15, 2009

Intersystems Caché Column Mismatch

In one of my applications I deal with Caché, an object-oriented database systems from InterSystems. The application communicates with Caché through an ODBC driver. I added Caché as a linked server to my SQL Server 2005.

One of the queries invovled selecting all columns from a table. So I had no doubt that 

select A,B,C,D,AMT
from TBL 

query would work. Whenever I ran this query in SQL Manage Studio I got this message:

"OLE DB provider 'MSDASQL' for linked server 'LS' returned message 'Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done.' Cannot get the current row value of column LS..SCH.TBL.AMT from from OLE DB provider 'MSDASQL' for linked server 'LS' Could not convert the data value due to reasons other than sign mismatch or overflow"

By process of elmination I found out that the culprit is AMT. After some reading through Cache documentations [http://vista.intersystems.com/csp/docbook/DocBook.UI.Page.cls?KEY=GIC_INTRO ; and other places ] I solved this problem. Basically although the ODBC presented the AMT column as Currency or [decimal in the linked server] that did not mean that Cache really stored only decimal in that column. And somehow that column contained alphabet characters which caused the query to fail every time it asked for the AMT column.

And to solve this problem through SQL Server I ran the following query instead

SELECT A,B,C,D,AMT
FROM 
OPENQUERY(LS,'SELECT A,B,C,D,convert(nvarchar(50),AMT) as AMT FROM TBL');

I ran into other problems with other columns and the cause is basically the discrepancy between the way the ODBC driver sees Cache columns and their datatypes and the actual layout of these columns in Cache. And openquery does a good job in helping to solve this problem.



Tuesday, February 10, 2009

Computing Science and Computers History

One of the things I like is computer science history, what was computing like a decade or two ago and was interesting and the such. Here is a talk given by Bill Gates in 1989 hosted by the University of Waterloo Computer Science Club [http://csclub.uwaterloo.ca/media/1989%20Bill%20Gates%20Talk%20on%20Microsoft
I listened to a good portion of the talk a while back and from a history persective I liked it specially the talk on OS/2.


Monday, January 26, 2009

Using Report Services 2005 Web Service

EDIT: Your problem may be easily solved if you read this first http://alsaydi.blogspot.com/2010/11/consuming-reporting-services-2005-web.html 

Today I wrote a very simple application that connects to Reporting Services 2005 web service.
The Web Services URL is:

http://[servername]/ReportServer/ReportService2005.asmx

Many sources give the following lines of code as a sample (assuming you have all the proper using statements)

ReportingService2005 rs = new ReportingService2005();
rs.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
CatalogItem [] items = rs.ListChildren("/Sales Reports", true);

I first tried this with Visual Studio 2008 and noticed that there is no ReportingService2005 class. The closes class ReportingService2005SoapClient. So I switched to Visual Studio 2005 and the VS IntelliSense showed ReportingService2005 and my code worked.

After a some time of playing around I found a way to get the code to work in VS2008.

The app.config file of t he VS2008 a couple of changes needs to be made:

the binding tage , the property allowCookies has to be set true (I think not sure)


<security mode="TransportCredentialOnly">                                          
<transport clientCredentialType="Windows" proxyCredentialType="Windows"
realm="" />
</security>



This simple will use Windows integrated authentication.
One more line of code is need to allow impersonation:
rs.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

assuming rs is an instance of ReportingService2005SoapClient.

So a sample code looks something like the following:

ReportingService2005SoapClient rs = new ReportingService2005SoapClient();
rs.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
CatalogItem[] items;
rs.ListChildren("/", true, out items);
dataGridView1.DataSource = items;

Cool things can be done through RS2005 Web Service!

Saturday, January 24, 2009

Windows Resource Toolkit

Windows resource kits, can be obtained from here (http://www.microsoft.com/downloads/details.aspx?familyid=9d467a69-57ff-4ae7-96ee-b18c4790cffd&displaylang=en), has some really valuable tools. I use cdburn often. Yesterday I was playing with remapkey.exe and I can see some good uses for it and some evil (annoying ) ones too.

A more important utility in the kit is a utility that lets you search multiple servers events logs. This can be really helpful when debugging a problem in a domain eventcombmt.exe.

oh.exe lists open hanldes is another useful utiltiy in the kit.


Thursday, January 22, 2009

كلام قيم لأبي حامد الغزالي



بلغني أن كتبا تؤلف من قبل مسلمين كيما في حد رأيهم ترد على نظريات أتى بها العلم الحديث . هذه الكتب و الله , تخلق
 تعارضا من حيث لا يوجد و يا ليت من يكتبها أو يدافع عنها قرأ شيئا من تهافت الفلاسفة للغزالي رحمه الله.الإمام أبو حامد الغزالي عاش في نهاية القرن الخامس الهجري أي بعد بداية فترة النشاط العلمي الإسلامي و بعد مرحلة الترجمة من كتب  اليونان و الإغريق إلى العربية.  وهذا إضافة إلى مقام هذا العالم الجليل يجعل رأيه قيما جدا في الرد على من يريد أن يعارض نظريات علمية ثابتة بقوانين عقلية رياضية و فيزيائية بناءاً على فهم معين من لديه لآيات من القرآن الكريم و الأحاديث النبوية الشريفة. فمن ذلك الكتاب أنقل ما يلي. حيث قال المؤلف في مقدمة الكتاب مبينا ما سيتعرض له الكتاب و ما ما لا يتعرض له الكتاب في رده على الفلاسفة 

"القسم الثاني: ما لا يصدم مذهبهم (أي الفلاسفة) فيه أصلاً من أصول الدين، وليس من ضرورة تصديق الأنبياء والرسل منازعتهم فيه، كقولهم: إن كسوف القمر، عبارة عن انمحاء ضوء القمر بتوسط الأرض بينه وبين الشمس، والأرض كرة والسماء محيطة بها من الجوانب، وإن كسوف الشمس، وقوف جرم القمر بين الناظر وبين الشمس عند اجتماعهما في العقيدتين على دقيقة واحدة.
وهذا الفن أيضاً لسنا نخوض في إبطاله إذ لا يتعلق به غرض ومن ظن أن المناظرة في ابطال هذا من الدين فقد جنى على الدين، وضَعَّف أمره، فإن هذه الأمور تقوم عليها براهين هندسية حسابيَّة لا يبقى معها ريبة. فمن تطلَّع عليها، ويتحقَّق أدلّتها، حتى يُخبر بسببها عن وقت الكسوفين وقدرهما ومدة بقائهما إلى الانجلاء، إذا قيل له إن هذا على خلاف الشرع، لم يسترب فيه، وإنما يستريب في الشرع، وضرر الشرع ممَّن ينصره لا بطريقه أكثر من ضرره ممّن يطعن فيه بطريقة. وهو كما قيل: عدوّ عاقل خير من صديق جاهل." 
فتأمل قوله أن هذه الأمور مبنة على مبادئ هندسية رياضية لا يبقى بعد النظر فيها ريبة لصاحب عقل. ثم انظر إلى تبيينه أن ضرر الشرع ممن ينصره لا بطريقه أكثر من ضرره ممن يطعن فيه بطريقة اه. فليت قومي يعلمون. 
ثم يقول الغزالي مستطردا :

وأعظم ما يفرح به المُلحدة، أن يصرح ناصر الشرع بأن هذا، وأمثاله ( اي ألامور الثابتة بالراهين الرياضية) على خلاف الشرع، فيسهل عليه طريق إبطال الشرع، ان كان شرطع امثال ذلك. وهذا: لأنّ البحث في العالم عن كونه حادثاً أو قديماً، ثم إذا ثبت حدوثه فسواء كان كرة، أو بسيطاً، أو مثمناً، أو مسدّساً، وسواء كانت السماوات، وما تحتها ثلاثة عشرة طبقة، كما قالوه، أو أقلّ، أو أكثر، فنسبة النظر فيه الى البحث الالهىّ كنسبة النظر الى طبقات البصل وعددها وعدد حبّ الرمان. فالمقصود: كونه من فعل الله سبحانه وتعالى فقط، كيف ما كانت." فالله المستعان.

من أجمل ما قرأته لأحمد شوقي رحمه الله ما قال 
رُدَّت الروحُ على المُضْنَى معكْ 
أحسن الأيام يوم أرجعك

تجد بقية الأبيات هنا 



Windows Console Program to Eject CD-ROM

I find the *nix command "eject" very convienent to eject cd/dvd. There is not builtin command in Windows but microsoft has a sample code here http://support.microsoft.com/kb/q165721/ that does just that. Here is the code with few modification i made. The syntax of the command is eject.exe {driver letter} [/c]. The /c switch is to close the drive bay.

/**
http://support.microsoft.com/kb/q165721/
*/
#include
#include
#include
#include
// Prototypes
BOOL EjectVolume(TCHAR cDriveLetter);
HANDLE OpenVolume(TCHAR cDriveLetter);
BOOL LockVolume(HANDLE hVolume);
BOOL DismountVolume(HANDLE hVolume);
BOOL PreventRemovalOfVolume(HANDLE hVolume, BOOL fPrevent);
BOOL AutoEjectVolume(HANDLE hVolume);
BOOL CloseVolume(HANDLE hVolume);
BOOL EJECT = TRUE;
//default is to eject device;
but a command switch can tell program to close cdrom
LPTSTR szVolumeFormat = TEXT("\\\\.\\%c:");
LPTSTR szRootFormat = TEXT("%c:\\");
LPTSTR szErrorFormat = TEXT("Error %d: %s\n");
void ReportError(LPTSTR szMsg)
{
    _tprintf(szErrorFormat, GetLastError(), szMsg);
}
HANDLE OpenVolume(TCHAR cDriveLetter)
{
    HANDLE hVolume;
    UINT uDriveType;
    TCHAR szVolumeName[8];
    TCHAR szRootName[5];
    DWORD dwAccessFlags;
    wsprintf(szRootName, szRootFormat, cDriveLetter);
    uDriveType = GetDriveType(szRootName);
    switch(uDriveType)
    {
        case DRIVE_REMOVABLE:
        dwAccessFlags = GENERIC_READ | GENERIC_WRITE;
        break;
        case DRIVE_CDROM:
        dwAccessFlags = GENERIC_READ;
        break;
        default:
        _tprintf(TEXT("Cannot eject.  Drive type is incorrect.\n"));
        return INVALID_HANDLE_VALUE;
    }
    wsprintf(szVolumeName, szVolumeFormat, cDriveLetter);
    hVolume = CreateFile(   szVolumeName,
    dwAccessFlags,
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    0,
    NULL );
    if (hVolume == INVALID_HANDLE_VALUE)
    ReportError(TEXT("CreateFile"));
    return hVolume;
}
BOOL CloseVolume(HANDLE hVolume)
{
    return CloseHandle(hVolume);
}
#define LOCK_TIMEOUT        10000       // 10 Seconds (1 s == 1000 ms)
#define LOCK_RETRIES        20
BOOL LockVolume(HANDLE hVolume)
{
    DWORD dwBytesReturned;
    DWORD dwSleepAmount;
    int nTryCount;
    dwSleepAmount = LOCK_TIMEOUT / LOCK_RETRIES;
    // Do this in a loop until a timeout period has expired
    for (nTryCount = 0;
    nTryCount &lt;
    LOCK_RETRIES;
    nTryCount++)
    {
        if (DeviceIoControl(hVolume,
        FSCTL_LOCK_VOLUME,
        NULL, 0,
        NULL, 0,
        &dwBytesReturned,
        NULL))
        return TRUE;
        Sleep(dwSleepAmount);
    }
    return FALSE;
}
BOOL DismountVolume(HANDLE hVolume)
{
    DWORD dwBytesReturned;
    return DeviceIoControl( hVolume,
    FSCTL_DISMOUNT_VOLUME,
    NULL, 0,
    NULL, 0,
    &dwBytesReturned,
    NULL);
}
BOOL PreventRemovalOfVolume(HANDLE hVolume, BOOL fPreventRemoval)
{
    DWORD dwBytesReturned;
    PREVENT_MEDIA_REMOVAL PMRBuffer;
    PMRBuffer.PreventMediaRemoval = fPreventRemoval;
    return DeviceIoControl( hVolume,
    IOCTL_STORAGE_MEDIA_REMOVAL,
    &PMRBuffer, sizeof(PREVENT_MEDIA_REMOVAL),
    NULL, 0,
    &dwBytesReturned,
    NULL);
}
AutoEjectVolume(HANDLE hVolume)
{
    DWORD dwBytesReturned;
    if(EJECT)
    return DeviceIoControl( hVolume,
    //        IOCTL_STORAGE_LOAD_MEDIA ,
    IOCTL_STORAGE_EJECT_MEDIA ,
    NULL, 0,
    NULL, 0,
    &dwBytesReturned,
    NULL);
    return DeviceIoControl( hVolume,
    IOCTL_STORAGE_LOAD_MEDIA ,
    //        IOCTL_STORAGE_EJECT_MEDIA ,
    NULL, 0,
    NULL, 0,
    &dwBytesReturned,
    NULL);
}
BOOL EjectVolume(TCHAR cDriveLetter)
{
    HANDLE hVolume;
    BOOL fRemoveSafely = FALSE;
    BOOL fAutoEject = FALSE;
    // Open the volume.
    hVolume = OpenVolume(cDriveLetter);
    if (hVolume == INVALID_HANDLE_VALUE)
    return FALSE;
    // Lock and dismount the volume.
    if (LockVolume(hVolume) && DismountVolume(hVolume))
    {
        fRemoveSafely = TRUE;
        // Set prevent removal to false and eject the volume.
        if (PreventRemovalOfVolume(hVolume, FALSE) &&
        AutoEjectVolume(hVolume))
        fAutoEject = TRUE;
    }
    // Close the volume so other processes can use the drive.
    if (!CloseVolume(hVolume))
    return FALSE;
    if (fAutoEject)
    if(EJECT)
    printf("Media in Drive %c has been ejected safely.\n",
    cDriveLetter);
    else
    {
        if (fRemoveSafely)
        {
            if(EJECT)
            printf("Media in Drive %c can be safely removed.\n",
            cDriveLetter);
        }
    }
    return TRUE;
}
void Usage()
{
    printf("Usage: Eject [/C] \n");
    printf("When /c is supplied, the program will close CD-ROM bay\n\n");
    return ;
}
void main(int argc, char * argv[])
{
    if (argc &lt;
    2)
    {
        Usage();
        return ;
    }
    if(argc == 3)
    {
        if(strlen(argv[2])&gt;
        1 && argv[2][1] == 'c' || argv[2][1]== 'C')
        {
            EJECT = FALSE;
        }
    }
    if (!EjectVolume(argv[1][0]))
    {
        printf("Failure ejecting drive %c.\n\n", argv[1][0]);
        Usage();
    }
    return ;
}