25
Jul/10
0

Refactoring a server side creating of JavaScript with C# verbatim literal strings (@)

Today I was refactoring a code of my job colleagues and stuck in horror (coding).

Beware Coding Horror on the way….

codinghorror

In one method I found this code:

string summary = String.Empty;
int counter = 0;
int i = 0;

foreach (PoiMapData poi in listAllPoi)
{
  string name = poi.KindName.Replace(" ", "_");
  string lat = poi.Latitude.ToString().Replace(",", ".");
  string lon = poi.Longitude.ToString().Replace(",", ".");

  summary = Helper.GetLeadingHtml(poi.Summary, 150);
  summary = summary.Replace("'", "\\'");

  string title = poi.Title.Replace("'", "\\'");

  i = poi.Id;

  ScriptString += "\t" + @"var point" + i + @" = new GLatLng(" + lat + ", " + lon + ");\n" + "\t" +
                       @"var marker" + i + @" = createMarker(point" + i + ", '" +
                       @"<span class=""title"">" + @"<a href=""PoiDetail.aspx?poiID=" + poi.Id + @""">" + title + @"</span><br />" +
                       "', '" + @"<br /><span class=""summary"">" + summary + @"</span>" + "', " +
                       "icon" + poi.KindId + ", " + "'" + name + "');\n " + "\t" +
                       "map.addOverlay(marker" + i + ");\n" + "\t" +
                       "listaPOI[" + counter + "] = marker" + i + ";\n\n ";
  counter++;
}

Holy Hejlsberg! If I may say :) I think this screaming Concatenation explains how very, very, and super very wrong this code is, and this is not all, because this piece of code is in foreach loop so it would continue over and over and over again. Horror!

…And this is still not all! Forget about speed and benchmarking, and for a second think what is most important in code: maintainability and readability, woohooo, can you even read above code. It is totally cluttered with “+”, “\n”, \t”, “@”!

But all that code doing is script (JavaScript) with GoogleMaps markers of all Points of interest, so it can be represent on map. But problem is that this JavaScript building is done on sever-side, using database for getting all Points of interest (there is also a grouping by kind of points of interest, but never mind that, back to refactoring).

So what is the best way to format and build formated JavaScript in C# language? For me it is by using, so called, verbatim literal string. In C#, is used @ sign (“monkey” as many would say, but actually is “at” sign) to indicate the verbatim literal string.

So what a hella heck is verbatim literal string. According to MSDN:

By prefixing a string literal with “@”, you can insert line breaks and other special characters into a string, and the C# compiler will interpret everything between the open and closing quotation marks as the contents of that string. Note that quotation marks within the string need to be doubled, or else the compiler will assume it has hit the end of the string literal.

So now is easy to refactor above shown horror. First why there is variable i, i is very popular in for loops, indicating index, but here uses point of interest Id. Why?!!. Actually, I would rename counter to index, or maybe use a for loop here better and some naming of variables are totally wrong, but let it be, that can pass, we want to refactor this concatenation coding horror…

Stop!
Refactoring time!

string summary;
ScriptString = String.Empty;
int counter = 0;

foreach (PoiMapData poi in listAllPoi)
{
  summary = Helper.GetLeadingHtml(poi.Summary, 150);
  summary = summary.Replace("'", "\\'");

  string script =
    @"{0}
      var point{1} = new GLatLng({2}, {3});
      var marker{1} = createMarker(point{1},
                                   '<span class=""title""><a href=""PoiDetail.aspx?poiID={1}"">{4}</span><br />',
                                   '<br /><span class=""summary"">{5}</span>',
                                   icon{6},
                                   '{7}');
       map.addOverlay(marker{1});
       listaPOI[{8}] = marker{1};";

  ScriptString = String.Format(script,
                               ScriptString,                               // {0}
                               poi.Id,                                     // {1}
                               poi.Latitude.ToString().Replace(",", "."),  // {2}
                               poi.Longitude.ToString().Replace(",", "."), // {3}
                               poi.Title.Replace("'", "\\'"),              // {4}
                               summary,                                    // {5}
                               poi.KindId,                                 // {6}
                               poi.KindName.Replace(" ", "_"),             // {7}
                               counter);                                   // {8}

  counter++;
}
  • I’ve removed many local variables, I just don’t see no purpose for their existence, especially famous (i)?!!.
  • Create a string that will hold formatting in a placeholders ({0},…).
  • In String.Format, first is ScriptString which is simulating “ScriptString +=” concatenation.
  • Rest are those needed for GoogleMaps marker(s).
  • String.Format could be in one line of code but I put comments of what number placeholder has, only for easier reading.
  • Verbatim literal strings keep all formatting so there is no need for tabs, newlines, etc..

Even though this will produce “fat” (full of white-spaces) script, this code should be only used for development, and for deployment I would rather crate one flat script probably. Done preferably with StringBuilder.

Here are some nice blog post of prominent bloggers I’ve found while refactoring this coding horror:

Happy coding and refactor your ugly code every now and then.

It’s good for the soul!

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • DotNetKicks
  • DZone
  • eKudos
  • HackerNews
  • LinkedIn
  • Live
  • PDF
  • Reddit
  • Slashdot
  • StumbleUpon
  • Yahoo! Bookmarks
  • MSN Reporter
  • NewsVine
15
Jun/10
0

SQL Server Dump with Powershell for backup

The first database that I did something useful was MySQL. I must admit I like that RDBMS but one thing that struck me, was how easy it is to dump whole database to a file.

So, I made script and put it in cron (a linux based Task Scheduler). The compression of file was by 7zip, not very planetary known, but awesome and best compression I’ve found.

The script backup.sh looks like this:

#!/bin/bash

FILE="dump-`date +%Y-%m-%d`.sql"

mysqldump -u root -psecretpass -c -e -K -r $FILE databasename

7z a -t7z $FILE.7z $FILE -m0=BCJ2 -m1=LZMA:d23 -m2=LZMA:d19 -m3=LZMA:d19 -mb0:1 -mb0s1:2 -mb0s2:3

rm $FILE

So, since last two years I’m working mostly in SQL Server. I tried to find the way to create this kind of script. I really don’t like SQL Server backups (.bak). I was a very astonished, for there’s no way for fully dump the SQL Server Database. The only way I found is through SQLDumper. A small software for dumping only INSERTs. Tables creation are not included, I wondered why, but this was my only option!

I wanted to use Powershell for scripting, and transition of upper bash code to Powershell was a quite a journey to me, it wasn’t easy but after few hours of searching, reading powershell documentation, I finally did it.

The script backup.ps1 looks like this:

$FILE="Backup_$(Get-Date -format "yyyy-MM-dd_HH-mm").sql"

.\SQLDumper.Console /filename=.\Backup.xml

ren .\backup.sql "$FILE"

.\7z a -t7z "$FILE.7z" "$FILE" -m0=BCJ2 -m1=LZMA:d23 -m2=LZMA:d19 -m3=LZMA:d19 -mb0:1 -mb0s1:2 -mb0s2:3

rm "$FILE"

echo Done...

A quick walkthrough of the script:

  1. Create variable $FILE to hold the name of file with current date and time, and sql file extension
  2. With SQLDumper console application create dump of database INERTSs (a backup.sql file), through the SQLDumper XML Templates (Backup.xml)
  3. Renaming backup.sql to meaningful name (from $FILE variable, with Date and Time of backup)
  4. Compressing the file with 7zip
  5. Remove the .sql file
  6. Done…

SQLDumper

SQLDumper has a GUI and console application. To easily crate the SQLDumper XML template, for first time is needed to run GUI version. Though it can be done manually by writing XML.
Steps are very easy in GUI environment:

  1. Connect to Database
  2. choose tables/fields
  3. choose the directory to put the dump file (in my case D:\backup)
  4. file name for backup file (in my case backup.sql)
  5. save this template by File->Save Template.

Note: be sure to use the 3+ version of SQLDumper, because the earlier release of SQLDumper console was very hard to use as script. I couldn’t run the command as scheduled script, because in some strange way SQLDumper had “Press any key to continue…” at the end of the script, and script was hanging there, waiting for key, and I didn’t know how to simulate key with powershell, so I used 3+ version, in which this strange behavior was removed.

Task Scheduler

Task Scheduler is very easy to use, so I’ll not going through it step by step. The only step I’ll go is that Task Scheduler need an Action, and for action is used “Start a program”. Since the powershell script can’t be referenced, there is need for usual batch (.bat) script.

The backup.bat script looks like this:

powershell -command "& 'D:\backup\backup.ps1' "

And also be sure that your scripts are Remotely signed to run. Beware this is a security risk, you should signed it with Certificate!

To remotely sign the powershell scripts use this command:

set-executionpolicy RemoteSigned

Hope it helps, if you have quetsions/modifications about the post, please do write!

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • DotNetKicks
  • DZone
  • eKudos
  • HackerNews
  • LinkedIn
  • Live
  • PDF
  • Reddit
  • Slashdot
  • StumbleUpon
  • Yahoo! Bookmarks
  • MSN Reporter
  • NewsVine
Filed under: Test Lab
24
May/10
0

Port WordPress/Joomla from Apache to IIS 7

This WordPress blog as one Joomla website that I maintain, have been until now on Linux hosting and I decide it to port them to my Windows hosting provider. My Windows hosting provider of choice is Arvixe, I really like Arvixe because they are following new technologies, that I need. They even supporting .NET 4 Framework, ASP.NET MVC, Unlimited SQL Server database as olso unlimited MySQL 5 database.

So, how to port the widely known blog engine and CMS. It is very easy, because in my case Arvixe have installed Rewrite Module for IIS 7. Porting was easy, I just move the files from Linux server to Arvixe Windows server, and also create new database, dump old and import it to new, easily done with phpMyAdmin.

But, all the problem, is to port .htaccess and rewrite script in to the IIS Rewrite script. No big deal each site have scripts available, for the IIS (and Apache). In case of WordPress all is needed to put in web.config inside <system.webServer>:

<rewrite>
    <rules>
        <rule name="Main Rule" stopProcessing="true">
            <match url=".*" />
            <conditions logicalGrouping="MatchAll">
                <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
            </conditions>
            <action type="Rewrite" url="index.php" />
        </rule>
    </rules>
</rewrite>

And in case of Joomla, same thing but little different script and include disable chache for php:

<rewrite>
    <rules>
        <clear />
        <rule name="Common Exploit Blocking" stopProcessing="true">
            <match url="^(.*)$" />
            <conditions logicalGrouping="MatchAny">
                <add input="{QUERY_STRING}" pattern="mosConfig_[a-zA-Z_]{1,21}(=|\%3D)" />
                <add input="{QUERY_STRING}" pattern="base64_encode.*\(.*\)" />
                <add input="{QUERY_STRING}" pattern="(\&lt;|%3C).*script.*(\>|%3E)" />
                <add input="{QUERY_STRING}" pattern="GLOBALS(=|\[|\%[0-9A-Z]{0,2})" />
                <add input="{QUERY_STRING}" pattern="_REQUEST(=|\[|\%[0-9A-Z]{0,2})" />
            </conditions>
            <action type="Redirect" url="index.php" appendQueryString="false" redirectType="SeeOther" />
        </rule>
        <rule name="Joomla Search Rule" stopProcessing="true">
            <match url="(.*)" ignoreCase="true" />
            <conditions logicalGrouping="MatchAll">
                <add input="{URL}" pattern="^/search.php" ignoreCase="true" />
            </conditions>
            <action type="Rewrite" url="/index.php?option=com_content&amp;view=article&amp;id=4" />
        </rule>
        <rule name="Joomla Main Rewrite Rule" stopProcessing="true">
            <match url="(.*)" ignoreCase="true" />
            <conditions logicalGrouping="MatchAll">
                <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                <add input="{URL}" pattern="(/|\.php|\.html|\.htm|\.feed|\.pdf|\.raw|/[^.]*)$" />
            </conditions>
            <action type="Rewrite" url="index.php/" />
        </rule>
    </rules>
</rewrite>
<caching>
    <profiles>
        <add extension=".php" policy="DisableCache" kernelCachePolicy="DisableCache" />
    </profiles>
</caching>

Hope it helps!

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • DotNetKicks
  • DZone
  • eKudos
  • HackerNews
  • LinkedIn
  • Live
  • PDF
  • Reddit
  • Slashdot
  • StumbleUpon
  • Yahoo! Bookmarks
  • MSN Reporter
  • NewsVine
Filed under: Test Lab
21
May/10
1

MySql Connector/NET 6.3.1 and Visual Studio 2010, what a mess

I just survived a real mess of installing latest alpha MySQL Connector for .NET (6.3.1), first when I downloaded it from, I think German mirror (SUNSite) there was no .msi file in mysql-connector-net-6.3.1.zip  only files like ones in “-noinstall” version. But after googling for an hour, found an .msi one version to download.

But, that is not all, running mysql.data.msi was not installing the product, it rollbacks the installation, with no error message at all. So I found one post on MySQL forum, one good soul has tried to debug Connector/Net on installation and found problem of “Config” folder in .NET Framework folders (x:\Windows\Microsoft.NET\Framework) .“Config” folder is only in CLR changed frameworks – 1.0, 1.1, 2.0, 4.0).  The problem was easily solved by renaming “Config” folder, for installation only, after renamed back to “Config”.

He (the guy from forum post) has problem with v1.1.43222, probably because he has one installed, I didn’t, so this wasn’t my problem, so I was stuck with this. But as I was reading through all replies (about 20+) to this post in forum, there was one reply, saying to rename all “Config” folder inside “Framework” folder.

This was like eureka to me, so I saw something interesting in “Framework” folder. Since I was following .NET 4 Framework from its early stages, I have had three “old” folders in it:

  • Old_v4.0.20506
  • Old_v4.0.21006
  • Old_v4.0.301280

And all of this folders have “Config” folders. I renamed it all to “Config0”, and only one not renamed “Config” folders was:

  • v2.0.50727
  • v4.0.30319

Now, mysql.data.msi installs just fine and there are no more mess with Connector/.NET, and everything works fine from integration with Visual Studio 2010 to using MySQL with POCO feature in Entity Framework 4, now available with .NET 4 Framework only.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • DotNetKicks
  • DZone
  • eKudos
  • HackerNews
  • LinkedIn
  • Live
  • PDF
  • Reddit
  • Slashdot
  • StumbleUpon
  • Yahoo! Bookmarks
  • MSN Reporter
  • NewsVine
Filed under: Test Lab