SVN Auto-commit files

Many times you would like to have a version control on your database. Here is a simple recipe how to set this up on you SQL Server datbase. And sometimes you need to set up automatic commits to SVN (or other version control system). Here is how to do it:

REM Script out database: all the tables, stored procedures, functions, etc.
REM then add missing files to the SVN version control
REM and commit all the changes to the repository.
REM Provide a comment for the commit as a parameter to this batch.
REM This is used as a scheduled task job - once a week do an automatic commit.

scriptdb -con:"Data Source=myServer;Initial Catalog=NorthenLights;user id=sa;pwd=password" -outDir:scripts -nocollation
cd d:\SQL_versioning\
"c:\Program Files\TortoiseSVN\bin\svn" add --force * --auto-props --parents --depth infinity -q
"c:\Program Files\TortoiseSVN\bin\svn" commit -m %1%

I hope I don’t need to tell you that you need to have TortoiseSVN installed, along with ScriptDB. If you are using SQL Server 2008, you can use my build for ScriptDb as the provided executable file does not work with SQL Server 2008 and 2012. Also don’t forget to modify the connection string for your database.

MySQL Backup script

Just for a future reference, mysql backup script:

#!bat
@REM echo off
@REM this script creates a backup of all the mysql databases in the designated directory.
@REM Please provide day of a week as a parameter

set file=d:\Mysql_backup\%1%_backup
mysqldump -u backuper --all-databases > %file%
7z a %file%.zip %file%
del %file%

-u backuper specifies the mysql user. This user must have a read access to all the databases. Provide a day of the week as a first argument.

Itenso TimePeriod library: change dates for TimePeriod

It took me a while to figure out how to change Start and End dates on an instance of TimePeriod. There are many functions to shrink and expand start and end dates, move the period by a certain time span, but I could not find anything that would just change .Start and .End.
Obviously you can do this:

timePeriod.Start = new DateTime(1999, 7, 9);
timePeriod.End = new DateTime(2012, 7, 9);

But this can lead to an exception if you are trying to move timeperiod to the future: Say start was on 1 Jan 2000, and on 1 Feb 2000. Then you give it .Start = 1 June 2000 and you get an exception saying “date out of range blah-blah”. That is because you are trying make start after end. You can swap assignment around, assign .End first then .Start. But you still can get an exception if you try to move the period to the past.

Instead, use .Setup method:

timePeriod.Setup(new DateTime(1999, 7, 9), new DateTime(2012, 7, 9));

And this should change your dates safely.

Disclaimer: I have not checked the source code, and not sure if that somehow ignores some internal mechanisms. So before blaming me that .Setup does not work, check with the author.

Remotely debug your web-site in Android phone

There was a light at the end of the tunnel. I have discovered something magical today. You can have you mobile web-site open on your phone, but debug it from your desktop.

It’s just pure magic!

Here is how to do it:

  1. Install Android SDK. Add  <sdk>/platform-tools/ to your PATH
  2. In Mobile Crome enable USB Debugging in Settings and connect your phone via usb to your PC
  3. In console run adb devices to check if you can see your device.
  4. In console run adb forward tcp:9222 localabstract:chrome_devtools_remote
  5. In your Desktop Chrome open http://localhost:9222
  6. Select the open tab from your mobile Chrome.
  7. Debug as normal.
  8. Profit!

via https://developers.google.com/chrome/mobile/docs/debugging

Alternatively you can create a create a bat file with the following:

adb forward tcp:9222 localabstract:chrome_devtools_remote
start http://localhost:9222

And run this bat every time you connect your phone to your PC. For ease of use you can set up this as AutoPlay action in Windows 7 (if you know how to do that).

Hint: Autoplay handlers are located in HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\AutoplayHandlers\Handlers But I have not managed to find out how to add the handler.

SP_SENDMAIL_DBMAIL How it Works, Stuck Emails and Purge InternalMailQueue.

I’m an enemy to myself. I’m writing a huge stored procedures and send emails in a loop. And sometimes that loop is infinite.

Anyway, today I had to figure out how to deal with SQL Server mailing functionality and sp_sendmail_dbmail. Every time you send email via sp_sendmail_dbmail, your message is going through the a huge number of checks and verifications. (Check out the source of sp_sendmail_dbmail procedure, it is on msdb database, inside System Stored Procedures folder.)

After all the checks you eventually will find insert statement: INSERT sysmail_mailitems ... Now look into sysmail_mailitems table. You’ll see there a list of all the emails that have been sent, will be sent or failed. There are few views to aid your viewing experience that aggregate data from sysmail_mailitems into something useful.

Looking at emails is fun Not this bit is a bit of black magic for me, but that is how I understand it. I could be wrong, don’t take it as a reference.

  • Whenever sp_sendmail_dbmail is executed, info about this email is inserted into sysmail_mailitems table and into InternalMailQueue which is not a table, but a queue. (Note for myself, lookup queues in SQL Server).
  • That queue is used by a Broker, and whenever there are records in the queue, Broker runs DatabaseMail.exe program.
  • The queue holds some information about new mail message and a reference to the record in sysmail_mailitems. So DatabaseMail.exe pops a record from the queue, reads respective message from sysmail_mailitems and sends an email as requested.
  • Now black magic part is almost over. When I have created a 3 million message queue with emails (infinite loop, remember?), all 3 millions records were in sysmail_mailitems and in InternalMailQueue. There are helper procedures to remove emails from the pending list:

    exec msdb.dbo.sysmail_delete_mailitems_sp null, ‘unsent’

This literally removes all the records from

sysmail_mailitems with emails that have not been sent yet. (First parameter is date – delete all records older than that date. Second parameter can take ‘sent’, ‘unsent’, ‘failed’, ‘retrying’) But that procedure does not touch anything in InternalMailQueue. So after executing sysmail_delete_mailitems_sp I was left with no records in the table, but all of them were in the queue. Now, when DatabaseMail.exe runs, it will find a lot of messages in the Queue, but no records about the mail to be sent. So it will create a lot of “FAIL!” records in sysmail_log table. To clean up InternalMailQueue at the moment I’m running this query:

#!sql
exec msdb.dbo.sysmail\_stop\_sp -- stop DatabaseMail.exe, so it does not try hard
ALTER QUEUE ExternalMailQueue WITH STATUS = ON
set nocount on
declare @Conversation_handle uniqueidentifier;
declare @message_type nvarchar(256);
declare @counter bigint;
declare @counter2 bigint;
set @counter = (select count(*) from ExternalMailQueue) -- count millions of queued messages
set @counter2=0
-- now do until nothing is left in the queue
while (@counter2&lt;=@counter)
begin
    receive @Conversation_handle = conversation_handle, @message_type = message_type_name from ExternalMailQueue    -- pop messages from the queue
set @counter2 = @counter2 + 1
end

exec msdb.dbo.sysmail_start_sp -- start DatabaseMail.exe again

EXEC msdb.dbo.sysmail_help_queue_sp -- verify that there is nothing left in the queue

Hopefully I won’t need this article again, but can be useful for somebody facing the same problem. Most of the details were spread around the internet, but I could not find the big picture.

Reference:

  1. Using and Managing Databse Mail
  2. Forum discussion about message clearing
  3. MSDN: Troubleshooting Database Mail: General steps
  4. MSDN: Database Mail Architecture
  5. Database Mail Setup – SQL Server 2005
  6. Found this after I have wrote this: SQL Server 2008 : Sending and Receiving with Database Mail

Ellipsis on long text in the table.

Sometimes you would like to shorten your long text in the HTML table. Here is the way to go with css and jQuery: css:

<table>
  <tr>
    <td class="ellipsis">
      Some very long text that you would like to be shortened
    </td>
  </tr>
</table>

CSS:

td.ellipsis {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 300px
}

jQuery:

$('.ellipsis').each(function (index) {
    var $this = $(this);
    var titleVal = $this.text();
    if (titleVal != '') {
        $this.attr('title', $.trim(titleVal));
    }
});

ScriptDB

A great and simple project that saves a lot of time for SQL Server Development: ScriptDB. Unfortunately have not been updated for 4 years already. And out of the box does not work with SQL Server 2008 and SQL Server 2012.

I have took the liberty to compile the project (thanks to the open-source!) against the newer libraries and now it works for SQL Server 2008 and SQL Server 2012.
Enjoy!

ScriptDB for SQL Server 2008 and 2012

Set Validation error in ASP.Net MVC Controller

Every time I need to set a validation error in a controller, I need to look up how to do this. But it is very simple. So I’ll just write it down here, for future reference: In controller do:

ModelState.AddModelError("FieldName", "Error message for User");

If you leave FieldName blank, the error will come up in validation summary. In a view you’ll have to do this:

@Html.ValidationSummary(true) // for the whole model
@Html.ValidationMessageFor(m => m.UserName) // for individual model field