Monday, April 13, 2009

Yahoo YUI Reading Blinds

Yahoo YUI Reading Blinds is a very nice browser tool based on JavaScript and YUI. Recently I tried to dig out more about this tool by looking its codes. Here are some of my findings.

First, the tool is based on a group of JavaScript codes. It is very long one like this:

javascript:var%20x=%20function(){var%20h=document.createElement('script');h.src='http://yuiblog.com/assets/readingblinds.js';h.type='text/javascript';document.getElementsByTagName('head')[0].appendChild(h)}();


This long line of codes does not have spaces. The spaces are actually specified by "%20" in codes. Then I break the codes in a nice format like this:

javascript:var x= function(){
var h=document.createElement('script');
h.src='http://yuiblog.com/assets/readingblinds.js';
h.type='text/javascript';
document.getElementsByTagName('head')[0].appendChild(h)
}();


In stead of putting this codes to toolbar, I added this tool as a new bookmark to my bookmark (I am using Vimperator and there is no toolbar visible). From the bookmark, I click on this. It works fine with reading blinds visible on top and bottom, very nice! I like this reading blinds more than others (you may find other reading blinds on web). It works well with with mouse movement and vertical scroll bar.



The only problem I had was that my Vimperator caches all the keystrokes. I could not use s, l, and b keys for smaller, larger and toggle. Vimperator blockes them to the tool. Fortunately, Vimperator has a "PASS THOUGH" mode to let all the keys passed: Control-Z.

This tool actually injects YUI JavaScript codes into the page: loading YUI scripts into <head> area. The scripts then adds top and bottom <div>s as blinds. In addition to that, it adds key and mouse event to move blinds.

I further hacker this tool to change the URL to the script src to my local Mac's Sites folder like this:

...
h.src='http://localhost/~[username]/YahooYUIReadingBlinds/readingblinds.js';
...


I added this to another bookmark as "YUI Reading Blinds Local Scripts". It works great! Since I download the readingblinds.js to my local site, I then made some changes to figure out how it works and to test its features with different settings. It was really fun to work with this tool.

The reading blinds will become darker if you click on the tool more than once. With FireBug enabled, I noticed that the scripts are injected more than once.

To get rid of this reading blinds, just refresh the web page. The original web page is reloaded and the JavaScript inject is gone.

The reading blinds does not work with https web URLs since https URL is an encrypted HTML protocol and no JavaScript injection are allowed.

This tool is a very good example to enhance web page display by using JavaScript injection!

By the way, I feel much easy to read web pages and my eyes are more relaxed with this great tool for a long period of time, especially with the browser maximized. I think this may protect screen as well.

Read More...

Friday, April 10, 2009

Code Syntax Highlight

toolsThe main reason I prefer to use Blogger than WordPress is that Blogger allows me to customize my blog layout with customized scripts and css styles in my blog template. For example, I have some blogs with source codes in C#, JavaScript, HTML, and SQL. It is very easy to include codes in a blog, by using <pre> tag. However, to highlight syntax, you need to sepcify style or to use css class style. Blogger provides this feature for free but you have to pay for this feature at WordPress.

Here are the steps I use to highlight my code syntax:

  1. Add some style to my blog HTML. This can be done through Blogger's Layout|Edit HTML. Check the Expand Widget Tempates to get the whole HTML layout settings and save it as backup before you make any changes.



    Add css classes (defined in { and } area) will be used to highlight code syntax.

  2. Generate HTML codes for my codes. I like to use some web's tools to get the job done. The tool I use is ASP.Net's forum page. I use this forum's post new topic editor to write/past my codes from its Source Code widget. The widget supports several languages which covers my areas. Those snap-shots are examples how I get my codes to HTML.

    1. Click on Source Code widget button




    2. Type in my codes




    3. Click OK to close it.

    4. Click on Edit HTML widget button




    5. Edit or copy the HTML codes



    6. Copy section HTLM codes between <pre ...> and </pre>


    Note: you may notice that ASP.NET's HTML codes contain some css classes. I added those classes to my Blogger's HTML template.

  3. In my blog entry, I paste the HTML codes to my blog. Normally I put the HTML codes between div tags. If the codes are not too long, I use the div with border. If the codes are too long, then I use a div with fixed height so that codes are within a block with scroll bar available to view codes.

    You can see those HTML tags by viewing section of codes (right click a selection of text).


There are many good tools available for syntax highlighting such as Google's syntaxhighlihter, SHJS, HIGHLIGHT.JS, and Highlight. The problem is that most of those tools are for people who have web server. I only have hosted web server like Blogger or WordPress. I cannot put any of my codes and css style files to the server. Blogger provides a way to embed css styles, but I would not want too many css definition codes there. It is just hard for me to maintain.

That's why I like to use ASP.NET's tool to get HTML codes with classes. Another great advantage of ASP.NET's widget is that it will be able to convert some special HTML codes such as > and <.

Read More...

Saturday, April 04, 2009

SQLite Manager Add-on for Fixfox

toolsI found a very handy tool: SQLite Manager an add-on for FireFox. I have been using another application called as SQLite Database Browser in my Mac for my SQLite databases. FireFox add-on actually is much better than the application, at least from the UI.

For example, the UI provides Database Settings for database generic settings and UIs for Views, Indexes and Triggers. The table UI layout is also much better than SQLite Browser.



I have not tried this one in Windows yet. I think it should work without any problem.

Read More...

Sunday, March 29, 2009

Dojo Chart Library

I read an article about Dojo Now With Chart Tools by Mattew Russell, the author of the book Dojo The Definitive Guide by O'Reilly.

The article lists several demos on generating charting by Dojox.charting library. I then started to copy the codes to an HTML file. Instead of loading Dojo libraries to my local computer even I have a personal web site on my Mac, I used xDomain reference to Google's Dojo CDN library. In this way, I don't need any web server and I can send this demo HTML to my colleagues to share it. My colleagues at my work really enjoyed it.

This demo does not only lists original JS codes. I enhanced the charts with different CSS styles and colors. It is so easy to do that. In addition to that, I allocate an 600x600 area at top as an area for chart and list my demos a UL list underneath it. This arrangement needs to clean the area for any chart previously displayed. The Dodo library does not provide APIs to clean chart. I finally found a way to clean it: simply removing all the childen nodes in the area. Even this one works, but it is not recommended. An Dojo insider pointed out this method does not clean all the objects created for the chart. I posted my question to StackOverflow and Dojo's forum.

My previous blog also mentioned the issue about xDomain reference. All these were really challenges for me since I am new in Dojo. I have not done much development in Dojo. However, the demo and enhancements let me learn a lots.

Here is my demo on Google's Code.

Read More...

Saturday, March 28, 2009

FireBug and xDomain Reference for JS APIs

Last week I read a very interesting article on Dojo's charting library. There are some demo codes in the web page. Instead of downloading Dojo's library to my local computer web site, I choose to use CDN fashion to load Dojo library from Google's CDN. This method is called Cross Domain Resource Reference or xDomain Reference.

In this way, I don't even need a web server. I just use VI to write an HTML file with JavaScript and Dojo API calls. That's the basic of web application: HTML + JS. I dropped the HTML file to my browser (FireFox) and it worked right away.

However, for the same codes which I found them in Dojo's ToolKit web page, one of feature does not work. It is the animation of curve chart. This feature is added by calling Magnify() API function to the chart. Behind sense, animation parts are created to each point. In the Dojo's web page, the magnification works fine but not in my HTML.

I spent about one day's time finally I figured it out. What I missed is to add the following codes to the head section of HMLT:

<head>
...
<script type="text/javascript">
...
dojo.require("dojo.fx");
...
</script>
</head>


FirBug helped me to find this one out. When I checked my HTML source codes in FirBug, the script loading section shows the loaded source codes in FireBug window. However, for the xDomain reference HTML page, the source codes are partially and they are displayed as one very very long line like this:


As you can see how hard to read when I copied the codes to VI:



Fortunately, the same codes are available on DojoToolKit web page, where Dojo's library files are not xDomain references. They are in the same domain. By using FireBug to take a peek inside the web page, I found the Magnify.js source codes are in nice layout:



By the way, I also tried to get source codes directly from Google's CDN web site, for example, Dojo.xd.js. It also displayed as a very very long line. But I went to DojoToolKit's web page to load the source code from their domain, I was prompt to save or open js. The download js file is in nice layout format. Here it reveals that CDN is not only for fast downloading, the size of the file is also very small. All the unnecessary codes such as line breaks are removed!

Read More...

Sunday, March 22, 2009

Using CTE in TSQL

Last week I found CTE (Common Table Expressions) when I posted a question to StackOverflow. CTE is an ANSI SQL-99 standard and it was added to Microsoft SQL Server 2005.

For me, it was new. I applied answers to my TSQL codes and then I really like it. It is so simple and readable. With its recursive power, I resolved my issue in a couple lines of codes. Today I further googled out more information about this and here are some links with good view of CTE:


Another example I tried was to replace T-SQL cursors by using both CTE and a table variable:
DECLARE @row INT;
DECLARE @rowMax INT;
DECLARE @myTable (
id INT IDENTITY(1,1) -- key with auto creament
name VARCHAR(100),
dt DATETIME );
-- Using CTE to select data into @myTable
WITH CTE_Temp(name, dt) AS
(
-- SELECT to hold a temp set of data
SELECT tagName as name, dt FROM myTagTable
WHERE version = 0;
)
INSERT INTO @myTable (name, dt) -- Insert to @myTable
SELECT name, dt FROM CTE_Temp;
SELECT @row = MIN(id), @rowMax = MAX(id)
FROM @myTable;
WHILE (@row <= @rowMax)
BEGIN
-- do someting about data in @myTable
SET @row = @row + 1; -- move to next row
END

Of course, this can be done with SELECT INTO FROM statement. This is just an example to use CTE to hold a section of data from a base table.

The power of CTE is its unique feature: recursiion. Within the WITH block, you can define two basic queries: base or anchor query and recursive query. Here is an example of Split like function to split a string by delimiter into a table as return:
CREATE FUNCTION [dbo].[udf_Split]
(
-- Add the parameters for the function here
@p_StringList NVARCHAR(4000),
@p_Delimiter NVARCHAR(512) = ';'
)
-- Return table definition
RETURNS @Results TABLE (
position int NOT NULL,
item NVARCHAR(MAX)
)AS
BEGIN

-- Use WITH statement with recursive power
WITH Pieces(pn, start, stop) AS
(
-- start from 1, 1, stop(=CHARINDX())
SELECT 1, 1, CHARINDEX(@p_Delimiter, @p_StringList)
UNION ALL
-- next to update pn, start and stop values
-- by recursive call

SELECT
pn + 1,
stop + 1,
CHARINDEX(@p_Delimiter, @p_StringList, stop + 1)
FROM Pieces
WHERE stop IS NOT NULL AND stop > 0
)
-- Test the result
-- SELECT * FROM Pieces;

INSERT INTO @Results
SELECT
pn, -- as position
SUBSTRING(@p_StringList, start,
CASE WHEN stop IS NOT NULL AND stop > 0
THEN stop-start
ELSE LEN(@p_StringList) END)
AS s -- as item by using SUBSTRING() function to get sub string from Pieces
FROM Pieces;

RETURN;
END

Read More...

Saturday, March 14, 2009

Use sp_who2() to Get Current Log-in User Information

Recently I have been working on Microsoft SQL Server 2005 to resolve some security issues. One question was to get the current log in user information.

As usual, when I cannot find an answer in 10 minutes, I post my request to StackOverFlow web site. I posted my question early in a morning before I went to my work. Quickly I got several answers when I arrived to my office by biking. I tried all of them and found out sp_who2, a undocumented stored procedure by Microsoft SQL Server, is the tool to get information I need. By using this tool, actually I can find out who is using the SQL server anytime. For example, if a critical data refreshing or migration job is scheduled, I could add this tool to find out if there is any user access to SQL server and send out warning emails if any one there, before the job is about executing.

It is very easy to user SP:

EXEC sp_who2;

The SP returns a list of log in users in a table view if you use Microsoft SQL Server Management Studio's query. However, I only want to see related column information and filter users by WHERE and ORDER BY clauses. Then I found out a way to define a table and output the result to a variable table like this:
DECLARE @retTable TABLE (
SPID int not null
, Status varchar (255) not null
, Login varchar (255) not null
, HostName varchar (255) not null
, BlkBy varchar(10) not null
, DBName varchar (255) null
, Command varchar (255) not null
, CPUTime int not null
, DiskIO int not null
, LastBatch varchar (255) not null
, ProgramName varchar (255) null
, SPID2 int not null
, REQUESTID INT
)
INSERT INTO @retTable EXEC sp_who2
SELECT Status, Login, HostName, DBName, Command,
CPUTime, ProgramName, BlkBy AS [Last CMD Time] -- *
FROM @retTable
--WHERE Login not like 'sa%' -- if not intereted in sa
ORDER BY Login, HostName;

To view all the user information, you need to login as sa or user with sa administrative privileges. Otherwise, you may only see yourself or limited information.

Read More...

Thursday, March 05, 2009

Using EXEC() AT Continued

My previous blogs on this topic demonstrate a way to use EXEC(...) AT ... to pass through a query to a linked server. The performance of this method is much better than a T-SQL query directly with the linked server. I tried it with an very big Oracle database table with great speed.

Today, I found another very interest issue with this pass-through query method. If the execution on the remote server has any error such conflict with constrains or wrong field name, the execution does not stop. The errors will be thrown at the end of execution. For example, the following codes will be executed completely:

DECLARE @sql NVARCHAR(MAX);
DECLARE @myCount INT;
-- Initialize setting
SET @myCount = -1; -- Initailize it
-- Build sql query

SET @sql = N'
BEGIN
SELECT COUNT(*) INTO :myCount
FROM owner.myTable
WHERE id1 = '
+ CAST(@id AS VARCHAR) + N';
END;'
;
-- id1 is an incorrect field name
EXEC (@sql, @myCount OUTPUT) AT linedOracleServer;
PRINT 'Count: ' + CAST(@myCount AS VARCHAR);
-- Prints Count: -1 Not stopped!


I tried similar codes with T-SQL directly using the lined server:
DECLARE @myCount INT;
-- Initialize setting
SET @myCount = NULL;
-- Use T_SQL query
SELECT @myCount = COUNT(*)
FROM linkedOracleServer.owner.myTable
WHERE id1 = 1;
-- NO prints, syntax error right away!
PRINT 'Count: ' + CAST(@myCount AS VARCHAR);


I found this interesting problem when I run a stored procedure with EXEC() AT to update value on Oracle side. It runs fine but today I found one error at the end of execution. The SP did not stop. Finally I figured out there were several violations of constraints. Since the whole stored procedure was completed and no exception to stop the program, the continuous codes set flags to mark insertion successful in another log table.

I tried to run a test scheduled job with this problem SP. The job log does indicate exception and step failure. However, the SP was executed completed.

EXEC() AT is a good way to leverage a remote server's full power; however, you have to be very careful about the process. Test your codes thoroughly before putting it into production. Another way may be to schedule a job to run the codes. If there is any failure, rollback any changes.

Read More...

Saturday, February 28, 2009

Using EXEC() AT with Oracle DB

My previous blog was about using OPENQUERY() method with an Oracle DB. The advantage of using this method call is to pass through a query to a linked server such as Oracle server and to leverage the Oracle server to do the job. The great benefit of this strategy is to obtain much fast performance compared to using a T-SQL query directly against an Oracle database object locally at SQL server.

However, when I tried OPENQUERY next day. I was so disappointed. What I found is that the query passed to OPENQUERY() must be a literal string, no variable or expression is supported. That means I cannot build a query string dynamically with different constrains. This greatly limits the usage of OPENQUERY. I just cannot use it in my projects.

Fortunately, I found another pass-through way to leverage Oracle's power to query data, and it is possible to pass result back. I spent about one and half day to figure it out. I posted several questions to StackOverflow web site but I did not get any answer there. Eventually I got the solution through Google searching. I posed my answer to StackOverflow as well.

The method is to use "EXEC (...) AT ..." to the job:

EXEC (@sql) AT linedOracleServer;

Actually, there are some good examples of using this method. However, all those examples are using either Microsoft SQL server or Express SQL server. By using pass-through query, the syntax of the query is very different from Microsoft SQL server and Oracle SQL server. That's why it took me a while to figure it out.

I can build an Oracle SQL query to combine all the inputs into a query string. That's an easy part. The most challenge issue is to pass results as output parameters. For example, I need to get total count of rows in an Oracle table with WHERE clause, and pass the result out to my SQL server.

Here is what I did:

DECLARE @sql NVARCHAR(MAX);
DECLARE @myCount INT;
-- Initialize setting
SET @myCount = NULL;
-- Build sql query
SET @sql = N'
BEGIN
SELECT COUNT(*) INTO :myCount
FROM owner.myTable
WHERE id = '
+ CAST(@id AS VARCHAR) + N';
END;'
;
EXEC (@sql, @myCount OUTPUT) AT linedOracleServer;
IF (@myCount IS NOT NULL)
BEGIN
PRINT
'I get the count from my Oracle table: ' +
CAST(@myCount AS VARCHAR);
END
ELSE
BEGIN
PRINT
'It must be an query syntax error';
END

The key points to build an Oracle query with an output parameter is to follow these steps:
  • making sure the query being a valid Oracle PL/SQL query such as SELECT ... INTO ... to assign result to a variable or parameter;
  • using ":" before a parameter name;
  • using an anonymous block (BEGIN...END) to wrap the query; and
  • Appending ";" at the "END" block.


One lesson I learned from this practice is that exceptions raised by "EXE () AT" may provide misleading error messages. For example, when I used "@" for parameter or missed ";" after END. I got somethink like "illegal characters in expression". You have to open your view in all different angles.

Read More...

Wednesday, February 25, 2009

Using OPENQUERY for Oracle DB

Today I googled an alternative solution to run an Oracle PL/SQL query or stored procedure from Microsoft SQL server 2005. I am very impressed by the result of this alternative way.

What I mean by an alternative way is that I have been using T-SQL queries directly against linked servers defined in Microsoft SQL server. A linked server is a server added to Server Objects->Linked Servers by using Microsoft SQL Sever Management Studio tool.



The linked server that Microsoft SQL server supports covers a variety of database servers, including Oracle server. By using T-SQL queries, you can easily query data from to any database object such as a table or view on this server in the same way as querying data from a local table or view, as in the following example:

SELECT COUNT(*) AS MyCount 
FROM myOracleServer..owner.tableName
WHERE ...;

where myOracleServer could be a linked server to an Oracle server.

One problem I troubles me is that when a table on Oracle side is very big(with millions of rows of data), the query may take a while to execute, sometimes more than 1 minute just for a query call. I had many cases to take more than 10 hours to update data from my Microsoft SQL server to an Oracle server with thousands of T-SQL calls(checking, updating and inserting data).

The alternative way I found today is to use OPENQUERY call like this:

SELECT MyCount 
FROM OPENQUERY(myOracleServer,
N'SELECT COUNT(*) AS MyCount FROM owner.tableName WHERE ...');

The execution time is 00:00:00 comparing 00:01:09 with the similar direct T-SQL query as above. It was a stunning when I saw the result back right away.

The information I found is from a discussion on Bytes web forum, where one person responded a recommendation by using OPENQUERY in a Google Groups' discussion. Then I figured out the solution that I need to improve my current T-SQLs.

The reason for such a big difference, I think o as my understanding, is that the SQL server may create a temporary table or allocate a cache for the database object referenced by a linked server in a T-SQL' query, while OPENQUERY is just a OLE DB connection call to the linked server with a SQL query by which the server or Oracle does its job with its full power.

Read More...

Sunday, February 22, 2009

T-SQL Tip: Combine Column Names as a String

I found following T-SQL query to build a string of selected column names together separated by command for a table. This string can be used then for another SQL query as a column list.

The first thing what I did is to use Coaslesce function to combine a list of row values into a string, separated by ',' if a value is not null or '' if null.

The second trick is to use information_schema.colums to get column names by column_name. Notice that table_name and column_name are a special key words here for table and column names.

1    DECLARE @v_FiledList NVARCHAR(MAX);
2 -- Use Coalesce to combine rows to a string
3 SELECT @v_FieldList = COALESCE(@v_FieldList + ',','') + column_name
4 FROM (
5 -- Use information_schema to get table's column names
6 SELECT column_name FROM information_schema.columns
7 WHERE table_name = 'myTable' AND
8 column_name NOT LIKE 'keyCol' -- filter col 'keyCol' out
9 ) AS A;
10 PRINT 'Field list: ' + @v_FieldList;

You can get more detail information such as data type, length, and so on from information_schema.columns:
SELECT column_name, * 
FROM information_schema.columns
WHERE table_name = 'myTable'

Read More...

Tuesday, February 17, 2009

jQuery Tutorial Videos

Today Ajaxian posted a group of tutorial videos on jQuery. I just finished the first one by John Resig, the designer and developer of jQuery. I saw a number of his training videos. The first one by Ajaxian's blog is for entry level:



Not sure what link is used for this embedded video, Adobe flash? The quality of the video is quite good, comparing to similar ones on YouTube.com.

By the way, the editor John used for the video is SubEthaEdit, an interesting editor with multi-user to work on one text file.

Read More...

Thursday, February 12, 2009

Vimperator Tip of the Day: xall Command

Tip of the DayIn my Firefox Preference, I have set up my tab settings to save all the tab as a session when it is closed and reopen the session when it starts.

However, sometimes this feature does not work. I get a blank tab occasionally and lost my previous tabs. I don't know why.

Today I found a Vimperator command to resolve the issue: xall command. Just type :x and then tab, this command is available for use. The description for this command is:

    Save the session and quit
or a snap-short:



Just remember to use this command close my Firefox from now on. I have add this key to My favorite Vimperator Keys.

The Power of Muscle Memory with Vimperator!

Read More...

Tuesday, February 10, 2009

Command Line Tool: curl

toolsToday I watched a video on Atom Publishing Protocol at YouTube.com GoogleDevelopers. Further reading on this topic, I found an article on this by IBM: Getting to know the Atom Publishing Protocol Part 1.

One thing that got my attention is the command line tool: curl. In my Mac terminal, I found this one is available. That's Unix world benefit. According to the manual information of curl(man curl):

curl is a tool to transfer data from or to server, using one of the supported protocols (HTTP, HTTPS, FTP, FTPS, SCP, SETP, TFTP, DICT, TELNET, LDAP, or FILE). The command is designed to work without user interaction.

That's a great tool. I like this one so that I can interact with a web server in command line. For example I tried this command to get a feed from a server:

curl -s -X GET http://heeds.beedburner.com/Macblogz?format=xml

Immediately I got returned strings back in the terminal. I tried to use Fixfox to open the feed but I could not GET result back in browser. Firefox prompted me to add it to my bookmark. By using curl tool, I can get the result back for analysis. It's a great tool to test and verify Atom Publishing Server or any web servers.

I don't think Windows cmd terminal has this one available. It might be something similar in PowerShell.

Read More...

Saturday, February 07, 2009

Caching Data and IFactory

Recently I have been working a project to extract data from a huge database server for a daily reporting service. The process generates data in a required format based a complicated business logic.

The structure of this project contains a Repository service as a gateway to provide interfaces to get domain objects by Domain classes. To retrieve data, I use IFactory pattern to get data:

interface IFactory<T> 
{
T CreateObject(IDBService);
}

where IDBService is an interface to provide methods to get data from database by using SQL.

The only problem with this strategy is that the process is too slow. It constantly makes SQL queries from the database, more than thousands SQL query calls.

I need a way to cache data to reduce those SQL calls at Repository. Since the data amount is none-predictable, I have to limit the cache. I use a maximum cache counter in the application configuration, 10000 as example. If the count of required data is less than this limit, then the Repository will cache all the data for later use. Otherwise, I have to get one data at a time.

The more I get into this caching feature, the better the process performs. With a maximum caching number, I reduced the SQL calls down to 8, and reduced the time from hours to minutes or less than 1 minute! That's great improvement.

For example, I created two factory classes for retrieving data:

public class SpectInfoListFac<List;<SpectInfo>> :
IFactory
{
...
List<SpectInfo> CreateObject(IDBSerivce db) {...}
...
}

public class SpectInfoFac<SpectInfo> :
IFactory
{
...
SpectInfo CreateObject(IDBSerivce db) {...}
...
}

For caching data, I used the first factory to get a list of data back if not too much data. The constructor of the factory provides information about the data and date range, as well as the maximum count number. If too much data or over the limit, the factory will return a null and I'll use the second factory class to get a specific data.

However,how about different levels of caching? Taking another finding people as example, if I want to find people with the name like "David Chu" and male from Canada, I may get too many. I could try with one more condition province = "AB", then city = "Calgary", then district area in "NW"... This will result in too many factory classes. Can I combine all these into one?

Here I changed the IFactory interface to a more generic way:

interface IFactory<T> 
{
IEnumerable<T> CreateObject(IDBService);
}

public class SpectInfoFac<SpectInfo> :
IFactory
{
...
IEnumerable<SpectInfo> CreateObject(IDBSerivce db, int level) {...}
...
}

There is only one method to create or retrieve objects. The level parameter is used for the granularity of data range. It will be up to the implementation Factory class to decide the level. For example, 0 for all, 1 for AB, 2 for Calgary...

The result is an enumerable collection. It could be a collection more than one, one for specified data item, or null for nothing being found.

Still I can have options with various implementations of IFactory class or one implementation to cover all the cases. My simplified factory pattern provides a caching option.

I love to re-factory of my codes!

Read More...

Sunday, February 01, 2009

Vimperator Tip of the Day: Show Sidebar Window


If you have not set your wideoptions to auto in your .vimperatorrc(for Mac) or _vimperatorrc(Windows), you may type the command to enable command auto-completion. Read details in my WordPress blog ....

Read More...

Saturday, January 31, 2009

Use Dropbox to Share Audios in Blog

I tried to update some audio files in my blog but I could not do it in Blogger. There is one option to add videos. When I tried this to update a mp3 file(about 3-4mb), it took me long time to upload. I had to give it up.

I have to use other web tools to load my mp3 files: Dropbox. This is a tool to share your files on web. If you install the application in your local computer either Mac or Windows, you can specify a folder to sync files between the computer and your Dropbox web server. One additional feature of this tool is that you can put files in public folder. Today I tried this one. It works perfect!

Here in my Mac, Control+click on a file in the public folder, you will see:



Copy the URL of public link, you can paste it to your blog like:

<img src="http://http://dl.getdropbox.com/u/268733/ChineseAudios/CCLesson.mp3" alt="dee" />

I verified that this feature is also available in Windows in a similar way.

The URL link is created when you upload a file to your public folder. It looks like a dynamically generated which does not have link to your Dropbox account. Anyway, it is a good way to put some files which you need to link to your blog to share.

Read More...

Monday, January 26, 2009

WordPress vs Blogger

I have tried WordPress for several days and posted several blogs there. It is good in terms of UI and some features such as rich templates and wedges like tag cloud. However, after digging several days, I find out there so many things are required with updates, such as spaces with medias and CSS styles.

I cannot add my own CSS styles to my templates so that my blog page cannot have default style classes for my code coloring. That's really bad. For images I had really hard time to find out a way to add to my posts, not as easy as Blogger. The only thing I was thinking to switch to WordPress is its UI, better than Blogger. For example, in the Compose mode I cannot add < char directly. I have to use &lt; instead. If I have a block of codes in clipboard, it will take me hard time to replace them.

However, I can still use the WordPress as well. I may use its Visual mode to convert these chars easily for me and then switch back to html mode to get the html source codes. I did the same thing by using ASP.Net forum's code generation piece to get color coded html source codes. By using WordPress I may reach to other people with the same interest. Just remember to post the same thing to two places, one with source and another is the link.

Read More...

Sunday, January 25, 2009

Vimperator Tip of the Day: Using Keys for Tabs

I have added a blog entry on my WordPress blog site: Vimerator Tip of the Day: Keys for Tabs.

Read More...

Tuesday, January 20, 2009

Live Mesh Devices Beta Available

Yesterday I learned from .Net Rocks audio talk on this new release from Microsoft. It is a tool to sync almost anything based on Web services or Cloud. I just tried this from iMac machine; unfortunately, it does not support Mac yet.

I have been used Dropbox to sync files between computers including Mac. Dropbox is only for file sharing with 2GB space for free. This tool is similar as Foxmarks, which is used to sync Firefox bookmarks.

Based on the information from the .Net Rocks talk, the Live Mesh is even bigger than those. It provides a framework for .Net developers to write services for various usages.

From my Mac, what I can do is to create folders on my Live Mesh Desktop. I think I can update or sync files with my local PC folders just like Dropbox.

Here is the picture of my Live Mesh:



I had my Firefox crashed when I browsing Live Mesh on my iMac.

Then I connected to my Windows though Remote Desktop Connection. I can view Live Mesh there and install Application Live Mesh, which is similar as Dropbox to sync files if I have files defined for sync. There is no more other features like services right now.

Read More...

Image Zoomer and Croppter

I read a new blog entry from Ajaxan on Dojo's demo on image zoomer. It is really cool. All the codes are based on Dojo and JavaScript.

There is one comment on this which provides another demo on image cropper UI. I know Prototype but never got chance to learn it. I only spent some time on Dojo at my iMac.

Read More...

Saturday, January 17, 2009

Vimerator Settings

Another feature of Vimperator is the settings. You can either set them dynamically or set in the configuration file, just like the way in Vim.

Here are two settings I think are very useful:


# enable hints for command mode
:set wildoptions=auto
# enable hints for links in command open mode. l or one.
:set cpt=l


Give these a try and see the difference. If you like them, you can add them to your Vimperator configuration setting file. In Windows, the file is _vimperatorrc in your %userprofile% directory; while .vimperator in your home for Mac.

When you open a link or type an Vimperator command with hint mode, you may see a list of hints available. Use Tab key to make a selection.

Updated: actually I found the same function of hints can be achieved without the settings. For example, press o to open a link with any word, link or blank. Press Tab key, then you will see a list of hints available. Same thing for any commands. For example, press :set then Tab, you will see a list of set commands available. Very cool, right? In addition to that, if you want to make a selection, just press tab key to make a selection.

Read More...

VIM + Firefox = Vimperator

I have used Vimperator for very long time. I can't believe that I don't have a blog on this issue. I think I started to use this after I read the blog by Jean Paul.

It is an add-on for Firefox. After the installation, all the menu, toolbar and address bar are invisible with maximum window of browser page. The only input place is on the bottom like this:



To use it, you have to use your keyboard to input command to control browsing, almost without mouse! just like using VIM or VI.

It took me about one week to taste the power of Vimperator. Now I cannot use my browser without it. Actually, I use just a few of keys only. Whenever I need a key for a feature normally used by mouse, I just search or read from the Vimperator help by F1 key in Windows or :help on Mac. Here is a list of keys I used commonly:


  • Esc key: escape from any mode. If you find out keys not working, you may in some mode such as search, Insert or other modes; Press Esc to escape;
  • [num]gt or C-n: go to next or nth (if num is provided) tab;
  • gT or C-p: go to the previous tab;
  • gf or :view: view the source in the current tab;
  • g0 or g^: go to the first tab;
  • g$: go to the last tab;
  • gh or gH: go to home page or new tab with home page;
  • gu or gU: go up parent link or root;
  • gi: focus the last used input field;
  • S-h or C-o: go to the previous history link;
  • S-l or C-i: go to the next history link;
  • f or F: hint mode to display links by number. F for open link in a new tab;
  • ;{keys}: hint mode by command keys:
    • a or s: save a link (prompt dialog or no dialog);
    • o or t: open a link in current tab or new tab;
    • O or T: open a link in current tab or new tab with its command in the command area(bottom);
    • v: view source code in the current tab;
    • y: yank the link;
    • Y: yank the link's text;
  • o or t: open a link in the current or new tab. You can type in a link in the command area then press enter key;
  • O or T: similar as above with the current link displayed;
  • y: yank the current link;
  • a or A: add or added the current link to bookmark;
  • [num]h,j,k, or l: move left, down, up or right by number if num is provided or by one as default;
  • gg: move to top;
  • G: move to button;
  • C-d, C-u, C-b or C-f: scroll down or up with half or full page;
  • z{keys}: zooming
    • i: zoom in;
    • o: zoom out;
    • z: back to 100%;
  • :sav[eas]>: save the current link to disk;
  • /: start search in Vimperator command area;
  • n or N: search forward or backward;
  • :st[op] or C-c: stop current loading;
  • r or R: fore to reload the current page(R for skipping the cache);
  • d or :quita[ll]: close the current tab or all tabs;
  • u or :undoa[ll]: undo closing one or all tabs;
  • :restart: restart Firefox;
  • :ZQ: quit and don't save current session;
  • :ZZ: quit and save the current session;
  • :ver: displaying versions of Vimperator and Fixfox;

That's just a small portion of keys in Vimperator! You can see there are not too many keys to be remembered. Actually, it is a muscle memory game. The more you use, the more they will be hard-burned to your brain. The keys will be naturally typed by your hands without thinking or looking. The result is fast browsing with easy!

Update: I posted the similar entry in my WordPress blog.

Read More...

Wednesday, January 07, 2009

DNRTV Traning Shows

During the time while I am in Wuhan, China, I have some time to browse web and get several DNRTV training shows viewed. DNRTV is my favourite web site for the new technology for .Net.

Shows 117 & 118 on The Entity Framework (part 1 and 2) is about the entity framework for data source connection and data mapping APIs. The cool part is that the data are retrieved only at the point the query is called and only the required data are retrieved instead of cache a lots of data on client side. The only thing I concerned is that the back end may use Ad hoc SQL query to get data.

Show 119 on XML Literals by Beth Massi is really cool. She demonstrated a way to use LINQ to do various things which normally needs a lots of codes. It makes the codes much easy to understand and maintain.

Scott Cate on EasyDB.com, show 121, demonstrate a very interesting cloud DB. This provides a way to get and manage data on web.

I like "Miguel Castro: Extreme WCF" (show 122) very much. This Miguel showed a new and well-structured way to build WCF applications. It reveals the logic and underneath parts of WCF and make applications much each to maintain. I like his way very much.

I just finished the show 124, Brian Noyes on Prism. The show demonstrates Prism, which is based on P&P's CAB or MVP. I used P&P CAB pattern before. The Prism makes the structure much clean and simpler than the previous version. It provides a framework for WPF applications. I am looking forward for the next part this show: commands and events in Prism.

Read More...

Tuesday, December 30, 2008

Const Class

I call it as const class since the class is used mainly for constants. I learned this this strategy when I used MVP for desktop applications. Concept is very simple, use this class to manage all the constants used in your application so that all the related constants are organized in a better structure.

For example, all the table name field names for a SQL table are defined in a class. Instead of hard-coded strings in your application, you can use this class to manage the table and fields names. I also added some query in the class to get some query SQLs. This makes the maintenance of my application much easier. Whenever I want to change the table or field or query strings, I know where to find them to make changes. No more need to search for the hard-code strings in my application.

Read More...

Parameterized SQL Query Over Ad Hoc SQL

I have been using Ad Hoc SQL query for very long time in various .Net projects, including ASP.Net. I realized the danger of SQL injection attacks, however, in most cases, I don't provide UI for client or hacker to enter any parks of SQL query. As most people mentioned that the reason of Ad Hoc SQL queries are used in most cases is based on the fact that most of examples codes are using Ad Hoc SQL queries.

Parameterized SQL query is better than Ad Hoc SQL query not only because it could prevent SQL injection attacks. It is better than Ad Hoc one in terms of performance. SQL server has ability to cache parameterized SQL query as stored procedure so that they could be compiled and executed in less time.

Based on the second reason, I have been convert most of SQL queries into parametrized SQL query. The conversion is actually very simple in most cases. I think this should be a rule for any applications with SQL related queies.

Read More...

Wednesday, December 17, 2008

WordPress

I have heard WordPress.Com many times and tried to browse its information. I think it is an open source based blogging tool. Anyway, today, I registered an account at WordPress with my new blog account here: chudq.wordpress.com. After I install the software, I may start blogging from the new site. A new experience for me!

Read More...

Network Drive Mapping in SQL Database Project

Today I tried to add a feature to map to a network drive in a .Net SQL database projjavascript:void(0)ect. The codes is based Windows API functions to map to a network drive. It works fine as a windows application. However, when I tried the same codes in my SQL database project, it fails to map to a network drive. I got an windows exception about something like a log on session failure (I need to use a user and password to make a map drive). The source codes is based on aejw.com's codes.

That's too sad. Maybe there are some other ways to get around this. One way is to run an external process to make a mapping by starting a process from SQL server. Another way may be something like described in this discussion on topic of C# Mapping a network drive, running a process of net.exe directly in C#.

Read More...

Remote Twitter Widget From My Blog

I have to remove the widget of Twitter from my blogger since I cannot access to my blog at work. The company I work does not allow me to access most web emails such as yahoo mail, hot mail and gmail. Recently Twitter is banned as well. No choice to do it.

Read More...

Tuesday, December 02, 2008

More on SproutCore

Just read an article on Cocoa for Windows + Flash Killer = SproutCore. The article provides in depth of SproutCore and its background stories. I really enjoying reading it. It looks like that SproutCore has strong support by Apple and has great potential to rock the web development and application development. Very exiting!

There is also another article on this at AppleInside: Apple's open secret: SproutCore is Cocoa for the Web.

Read More...

Saturday, November 29, 2008

SQL Send Email (3)

This is the continuing part of my previous two posts:

As I mentioned in the previous post, what I need is to save the content to an html file. The main reasona are: I need to get the size of the html content, and I have optiont to send the html content by attachment file. I could do the first one easily by calculating the length of variables which hold html strings and xml content. However, when I come to the point how to send the html content, I have to decide to sent it in the body of email or by a file attachment.

If the file size is too big, more than 10mb in some cases, it will cause mail application (outlook) hanging for a long time when the email is opened. In this case, it is better to send html as an attachment file. In addition to that, I could save the html file to a reporting server site so that a light notifiation email with a link to the html file could be sent.

I have posted several blogs on SQL Server Porjects. It is very easy to create a .Net project to save string to a file. Therefore, I created a SQL procedure .Net project to do the job. The store procedure is very simple:
public partial class StoreProcedures
{
[Microsoft.SqlServer.Server.SqlProdure]
public static void SaveToFile(
string content,
int overwrite0OrAppend1,
string fileName)
{
...
}
...
}

In the same way, I have created another .Net based SP to get file size. With these SPs,
here are some SQLs to save content vars to a file:
EXEC SaveToFile @htmlBefore, 0, @fileName;
EXEC SaveToFile @xml, 1, @fileName;

Finally, I use the following SQLs to send the HTML content by email:
IF @fileSize < @fileSizeLimit
BEGIN
EXEC
msdb.dbo.sp_send_dbmail -- SQL SP to send email
@receipients = @p_recipents, -- recipients passed by parameter
@subject = @v_subject,
@body = @v_content,
@body_format = 'HTML'; -- set content as HTML
END
ELSE
BEGIN
EXEC
msdb.dbo.sp_send_dbmail -- SQL SP to send email
@receipients = @p_recipents, -- recipients passed by parameter
@subject = @v_subject,
@file_attachments = @fileName, -- set attachment file
@body = @v_msg,
@body_format = 'HTML'; -- set content as HTML
END

Read More...

SproutCore Presentation

I just finished watching a show on SproutCore by Charles Jolley. Note: the real show starts after 20 minutes (the first part is on Google App Engine). It is very inspiration and a fresh view. I really like the SproutCore infrastructure.

His view on the current web applications is true. There are too much loads on the server side, data, html presentation, and business logic. Click and wait is a pain process for most web applications, and you rely on server availability to see web application content.

I have started to learn jQuey and Dojo recently. This is my evening part time exploring. All these tools are very good ones to move html presentation part to client side so that data can be retrieved and updated by using Ajax on cient's requests. SproutCore framework jumps one more further step, moving the server side business logic to client side. As a result, the server is very thin!

I think this is a new way to develop web applications and we will see more smooth and desktop like web applications on web. Enjoying the exploration!


Skip 20 minutes to start SproutCore presentation.

Read More...

Wednesday, November 26, 2008

Value2 in Excel VBA

I did a lots of VB programs long time ago. Actually, I started to develop Windows applications by using VB3.0 to VB6.0. Then since the .Net, I switched to .Net C# and VB.Net. However, VB6.0 still has its market. During this year my contract job, I have done a lots VBA applications for Excel, Word and some legacy applications which provides VB6.0 code scripts.

Anyway, I encountered one interesting issue today. I tried to use Value2 in Excel VBA codes to compare two date date types. I know that I put the same date from one worksheet to another worksheet. However, when I tried to search for the same date in another worksheet, the cells with dates are not matched:

v1 = sheet1.Cells(row, col).Value2
v2 = sheet2.Cells(col, row).Value2
If v1 = v2 Then
...
End If


When I changed Value2 to Value, these cells with the same dates are found.

I googled the Value2 and found out that Value2 does not use Currency and Date data types (ref MSDN Office developer center). These values are converted to double type. This conversion caused a very insignificant difference 0.###E-11. This difference makes them different!

By the way, I know that when float values saved in variables, the actual value is very close the "float value" such as 1.2 as 1.199999999, and the value might be dependent on CPUs or OS. That means a float values in one machine may not the exactly same as the value in another machine. For safe gard, when I compare two floating values, I always use absolute the difference to epsilon, same if less then epsilon, not same others.

However, when I looked at C#'s floating data types, I see Equal() operator or == for these data types. Not sure why they are there.

Read More...

Sunday, November 23, 2008

Thin Server Archetecture Using Dojo

Just watched a tech show on Youtube.com on Practical Thin Server Architecture Using Dojo:



This well explained the server oriented web development and thin server web development by using client side JavaScript. I have done many ASP.NET web applications. It is true that the server side dominates everything including client side UI's by sending HTML & XML streams from server side. It is very heavy coupled between server and client.

Actually, the most important part between server and client is the data to fill for the client side UI, or passing data with request to server to data source such as DB.

Dojo provides a very good way to provide client side JavaScript codes in Dojo API form so that UI can be easily build and quickly respond by utilizing client side CPU and resources. The Widget I just learned is very clean one, Rating widget. It encapsulates all the UI codes to display icons and events to update icons. The testing HTML page is very clean.

Then web service is another great tool to use: sending request to get and put data between client side and server side. The server could be different web servers. In this way, the web application is very scalable and can be done by components. I can see that many parts are all reusable. Compared to the current way to build web applications, I am getting better picture of those new tools I am interested: REST, Dojo, jQuery, GWT, and YUI.

Read More...

Saturday, November 22, 2008

A Dojo Widget: Rating

The title is a tutorial article on how to create a Dojo Widget: Rating by mindtrove' blog. I spent some evenings on this new adventure: Dojo Widget programming. I made some changes and tests to undertand how the Dojo's API working. It is a rewarding process.

Not All Browsers Support Dojo Widget Events

I tried it on Mac and Windows, Firefox, IE and Safari. The widget works fine in Firefox and IE. For Firefox, there was only one minor issue. When I have to Vimperaotr enabled, some keys are not working such as Left, Right, Home and End keys. What I found out is that those key events are trapped by Vimperator and never passed to the widget. After I set pass-through mode(Control-Z), the keys are working fine.

However, Safari is tough. It is a UI mouse driven based browser. It does not let key events to passed to the widget. Only a few HTML DOM controls such as button and text can receive focus but not for others like span. Not sure if there is any way to change Safari's blocking.

Separate Dojo Library from Widget Project

Mindtrove' structure is to put his widget in the folder of Dojo. I don't like this. I prefer to put my customer projects outside of Dojo. Therefore, I tried to put my files like in this structure:

-html (all the test hmtl files)
-images (all the image files)
-scripts
-dojo-release-1.2.0
-[dojo folders]
-mindtrove (customer widget)


The customer widget codes are in a separate folder mindtrove, in the same level of other Dojo API library folders.

Here is the codes to load Dojo library files:
<script type="text/javascript"
src="../scripts/dojo-release-1.2.0/dojo/dojo.js"
</script>

And JavaScripts codes to load the widget:

<script type="text/javascript">
dojo.registerModulePath("info.mindtrove",
"../../../scripts/dojo-release-1.2.0/mindtrove"
);
dojo.require("dojo.parser");
dojo.require("info.mindtrove.Rating");
...
</script>

I tried to move my widget up one level, but the localization files could be not loaded by i18n.js. It looks like that i18n.js does not support cross domain scripts (widget codes outside of Dojo library folder could be treated as cross domain loading).

Add Debug and Double Click Event

When I learn something like this Dojo widget, I always like to add something at the same time. This helps me a lot to better understand structure, logic and codes. As I mentioned above to move my testing html page and Dojo library files not at the root like original codes did.

In addition to that, I have added one more attribute or property called debugKeyCode in the widget. This property is a bool(true or false) data type. I use this property to display keyCode value in the span's Title or tooltip. The keyCode value is saved in the local var preKeyCode when onkeypress event is fired on span object. In this way, I'll be able to see the key codes. Here are some codes I added to Rating.js(under mintrove folder):
dojo.declare('info.mindtrove.Rating', [dijit._Widget, dijit._Templated], {
...
// After currentValue property I added two vars.
// initial value
currentValue: 0,
// Add a property for deug key code, see Rating.html template as well.
debugKeyCode: false,
// this is a related property value to hold previous key code
preKeyCode: "",
...
postCreate: function() {
...
this.connect(span, 'onclick',
dojo.hitch(this, this._onClick, i+1));
// listern for mouse doubleclick on the span with the value it
// represents in the index of star
this.connect(span, 'ondblclick',
dojo.hitch(this, this._onDoublClick, i+1));
...
},
...
/*
* Called when the user doubleclick a star.
*/
_onDoublClick: function(value, event) {
if ( this.currentValue >= value )
this.currentValue -= 1
this.currentValue = Math.max(this.currentValue, this.minimumValue);
this._update();
},
...
_getDescription: function() {
...
var str = dojo.string.substitute(template, [this.currentValue]);
if ( this.debugKeyCode &&
this.preKeyCode )
{
str = str + ' previous key code: ' + this.preKeyCode;
}
return str;
},
...
_onKeyDown: function(event) {
...
this.preKeyCode = event.keyCode;
...
}
});

In above codes I also added codes to handle double click event. Since Safari does allow span object to get focused and to get onkeypress event, I added this feature so that by using mouse, rating can be added and removed.

Using Firebug Addon
Firebug add-on is a great tool for developers. No only it saves you a lots of time and effort to debug JavaScript codes, but it also provides some information normally you cannot get from the browser.

For example, Dojo supports Firebug by using some attributes when Dojo library is loaded. If you enable two attributes in djConfig like in following codes, you will see the Get Dojo library files in Firebug's console tab. That great to see what is downloaded and what are failed if you set them in wrong location:
<script type="text/javascript">
var djConfig={
...
parseOnLoad:true,
isDebug:false
};
</script>



Another great feature of Firefbug is that you can view the dynamically created DOM elements. By using Dojo and jQuery, you can create DOM elements, change style class, do animations on fly. Normally, I would like to see those elements in html but they are not available from browser's View Page Source or View Selection Source. Firebug does reveal the dynamic changes. That's great help.

For example, if you view the HTML tab in Firebug for this Rating widget, you will see the spans dynamically created and hidden text as well. By learning this Widget tutorial, I discovered a lots of new things, both in Dojo and Firebug.

Read More...

Wednesday, November 19, 2008

JavaScript and Ajax for Web Applications

Just read an article about Fixing Web, Part 1 referred by Ajaxian blog. It mentioned leading three tools used by developers: jQuery, Dojo and YUI. I know the first two already, actually in the learning progress and very impressed by them, the last one is new.

YUI is Yahoo! User Interface Library with set of utilities and controls based on JavaScript. I went to Yahoo! developer site for YUI and watched the overview vedio. It is another very impressive tool I am going to learn.

As the article says, "We've made major progress on the web since 2005 and the rise of Ajax. JavaScript toolkits like JQuery, Dojo, and YUI have expanded what we can do with web browsers and increased our productivity...", I really like to sharp my skills with these great tools.

Read More...

Monday, November 10, 2008

Dojo Does Raise Exceptions

Dojo does raise exceptions in some cases. As I tried out some example codes from Dojo Quick Start Guide: Events, I got exceptions.

The following codes explains the case:

var mineObj = {
aMethod: function() {
console.log("Running mineObj method A");
},
bMethod: function() {
console.log("Running mineObj method B");
}
};
dojo.addOnLoad(function() {
// run bMethod() whenever aMthod gets run
dojo.connect(mineObj, "aMethod", mineObj, "bMethod");
//dojo.connect(mineObj, "aMethod", mineObj, "bMethod1"); // exception!
//dojo.connect(mineObj, "aMethod1", mineObj, "bMethod"); // OK
// start chain of events
mineObj.aMethod();
//mineObj.aMethod1(); // JavaScript error!
});

The second connect(commented out) will throw an exception in FireBug:
uncaught exception: dojo.hitch: scope["bMethod1"] is null (scope="[object Object]")

The connect fails to invoke method bMethod1 as it is not defined. However, the third connect call is OK.

The last commented out code is a JavaScript error in FireBug:
mineObj.aMethod1 is not a function

Read More...

No Exception On Dojo Chain Calls

I spend about 1 or 2 days a week on learning and exploring Dojo. I really like this JavaScript based API framework. I found one very nice feature of Dojo. Not only you can call Dojo methods by using Dojo chain calls, and you don't need to worry about if any middle part of the chain returns undefined or not.

For example, I added the following codes to the head's script section:

dojo.addOnLoad(function() {
console.log("OnLoad ready to add events");
dojo.query("#testHeadingEvent")
.style("cursor", "pointer")
.connect("onclick", function() {
this.innerHTML="I've been clicked";
});
console.log("Onload fires adding event on headEvent");
});
the query() function returns a DOM node by id. If the node is not found, it's still OK. No exception is thrown. I can still see the messages print out on the console(by using FireBug add-on). Isn't that nice?

Read More...

Saturday, November 08, 2008

SQL Send Email (2)

Microsoft SQL Sever 2005 supports xml data type. This data type provides a very convenient way to hold data from SQL SELECT statement. Continue from the previous blog, the following codes set xml with data from MyData table(id, name and value three columns):

DECLARE @xml xml;
DECLARE @htmlAfter NVARCHAR(MAX);
..
SET @xml =
-- Checks if count is 0 or not. Avoid NULL value in the result.
CASE
-- @count is a var to get the count from MyData table.
WHEN @count is null OR @count = 0 THEN null
ELSE
-- Get data from MyData table
-- Note: the three columns should match the previous
-- table header column definition (3 cols)

(SELECT
td = CAST(t.ID AS VARCHAR), '',
td = t.NAME, '',
td = t.VALUE, ''
FROM MyData t
FOR XML PATH('tr'), TYPE -- As XML output
)
END;

SET @htmlAfter = N'</table></div>'

The comments should well explain how to set xml in this example case. The reason I use xml data type is that it can hold large amount of data. I tried to use NVARVAR(MAX) before. In one case, the data retrieved by SELECT are millions rows of data and my var was overflowed with some data missing. When this happened, there was not any errors or indications. It took me a day to figure it out. With xml data type, The problem is gone.

The next article will continue to discuss how to use a SQL Database Project to save results to a file and get back text size information before sending out email.

Read More...

SQL Send Email (1)

I have created a stored procedure to send an email notification of some data. This is quite convenient to get notifications about database status, reports and any related business needs.

Basically, this is done by using Microsoft SQL 2005's build-in msdb.dbo.sp_send_dbmail. It looks like that some of email related SPs have been faded out since the SQL Reporting Service launched. The reporting services provides much versatile features and allow developers to design more ad-hoc web based reports. However, email notification still has its uniqueness and useful applications.

Since my SP is used for specific notification about data status, therefore, only one parameter is defined, as recipients of emails separated by comma.

The content of the email is HTML text. Depending on the length of text, if it less than the size of email limit(see my previous SQL Server Database Mail setting), then the data are formatted as HTML; otherwise, the file will be saved as a file and it will be attached to the email out.

The following codes set HTML header part:

DECLARE @headerHTML  NVARCHAR(MAX);
...
SET @headerHTML =
N'<html>
<head>
<script type=''text/javascript''>
function toggleIt(id) {
var post = document.getElementById(id);
if (post.style.display != ''none'') {
post.style.display = ''none'';
}
else {
post.style.display = '''';
}
}
</script>
</head>';

Here I added some JavaScript to hide and display detail views of data by function toggleIt(id). For example, the following codes define a title node with a link referenced to the function:
DECLARE @htmlTitle1 NVARCHAR(MAX);
...
SET @htmlBefore =
N'<a href=''javascript:void(0)''
onclick=''javascript:toggleIt("1")'';
style=''text-decoration:none'' title=''Expand/collapse this item''>
<H2>[+/-]My Data</H2></a>
<div class=''post-body''
id="1" style="display:none">
<table border="1">
<tr>
<th>ID</th>
<th>Name</th>
<th>Value</th>
</tr>'
;

After the link tag(a), the above codes add a table tag with a row of headers defined for the next data retrieved from SQL.

The next blog will continue on the topic on how to use xml type to hold SQL retrieved data.

Read More...

Tuesday, November 04, 2008

Enabling PHP for Apache Server in Leopard

While I was doing coding to learn Dojo, I reached one point that I needed PHP module enabled for my Mac Apache server. By default, it is not enabled.

I found information about enabling PHP for Apache Server. The steps are very simple, however, I did not have the right to edit the file httpd.config in /private/etc/apache2. The file is owned by root user. Soon, I found a way to edit the file: logging as root user, see my Mac blog entry.

After all these settings, I made my Dojo page working with php page. Basically, Dojo web page calls the server side php page to pass information back. It is very cool. This is also my first experience with PHP web page development. One lesson I learned is that for a php page, you have to indicate it by <?php and no space between ? and php.

Read More...

Monday, November 03, 2008

Doio: JavaScript Tool for Web Page Development

Today, I just started to learn Dojo. It is something very similar to jQuery. However, it provides core and APIs directly for Web Page development. It is very cool!

Just tried the Hello World example to display a button, to run Dojo script, to Get and Post back to server. I used my Mac with PHP to test it. It is very interest! The tool provides universal JavaScript APIs and you don't need to worry about brower syntax for DOM elements. I like it very much. This is another area I would like to invest my energy into it.

One neat thing about Dojo is that you don't need to install Dojo package or core APIs into your server. You can define <script ... src="http//..." /script> to either AOL developer's site or Google's developer's site. You will always have the updated engine for your Dojo scripts.

Read More...

Sunday, November 02, 2008

VIM, Initial Configuration and PlugIns

I have been used VIM for about weeks and started to fall in love with it. I am still in learning stage and found many some settings very neat.

The first thing is to configure VIM initial settings. This is done through the configuration file ~/.vimrc for Mac OS and C:\_rimrc for Windows. You can find many sites with good .vimrc file and use it as start. If you don't like some settings, you can change it.

Based on vimrc in the article of VIM Introduction and Tutorial, I made some changes. For example, I prefer the background color as white and tab as 2:

  "Tabs are 2 spaces:
set tabstop=2
"We use a white background, don't we?
set bg=white

I found some settings and added them in .vimrc:
  "Set characters shown for special cases such as:
"wrap lines, trail spaces, tab key, and end of line.
"(must be turned on whith set list)
set listchars=extends:»,trail:°,tab:>¤,eol:¶
"Set moving around at the end of line back to previous line by
" key and coursor keys, and normal movememt h and l keys
set whichwrap=b,s,<,>,h,l

"Enable C style indention
set cindent

I love special char setting, which displays tab, trial spaces, and end of line as special characters. I have to use command ":set list" to enable the setting. The move around setting enables backspace, arrow keys, and move keys h and l to move back previous lines.

There are many VIM plugins available. This is quite new for me. I found only one is working for me so far: Align. To use it, just type in the command ":Aligh =" when you in visual mode with several lines selected. Then the text will be aligned by = sign to separate left part and right part aligned by = sign.



After aligning, the text are aligned by =:



To install it, find the folder where the file "Align.vba.gz" located in Terminal. Type in the command:
  vim Align.vba.gz

The file is opened by VIM. Then typing the command to read scripts and then quit:
  :so %
:q

Reopen VIm again. The command :Align is available!

Read More...