Searching videos on YouTube is simple but if you know a few tricks, it becomes even more fun and accurate. The YouTube team has considerably simplified their video search function making it easier for people to perform advanced searches on YouTube without learning any complicated syntax. Let’s look at some real-world examples:
#1. Find a specific YouTube channel
royal wedding, channelYouTube will have numerous videos related to the royal wedding but if you are only looking for their official YouTube channel, add the word channel to your query separated by a comma.
#2. Limit your search to recently uploaded videos
oprah winfrey, this weekThis will only show recent videos related to Oprah that have been uploaded to YouTube in the past week. You may also use “today” or “this month” to limit your search to videos that were uploaded in the past month.
#3. Find only official videos, no fan material please
never say never, partnerIf you are looking for the ‘official’ Justin Bieber track and don’t want to see any parodies or fan material in the search results, add the word ‘partner’ to your search query.
#4. Find movies on YouTube
jackie chan, movieYes, you can find full-length movies on YouTube (including Bollywood titles). The search operator for finding movies is, you got it right, movie.
#5. Find high-quality videos on YouTube
the king's speech trailer, hdAdd the keyword hd to your search query and YouTube will only show High-definition video clips that are either 720p (1280x720) or 1080p (1920x1080 pixels).
#6. Find 3D video clips on YouTube
avatar, 3dGot a pair of 3D glasses? Add the keyword 3D to your search query and discover 3D videos. You may also enjoy some 3D content on YouTube without the glasses – see details.
#7. Find video playlists on YouTube
bryan adams, playlistPlaylists are a great option if you want to find and watch (or listen) multiple related videos in one go – like all the Old Spice commercials or your favorite Savage Garden tracks. You may also copy YouTube playlists to your own account.
#8. Find lengthy videos on YouTube
tom and jerry cartoons, longAdd the keyword long to your search query and YouTube will only return videos that are at least 20 minutes in length.
#9. Perform exact-match searches on YouTube
allintitle:"google goes gaga"You can borrow the popular allintitle search operator from Google on YouTube to perform exact title matches. Might be useful when the original video is not available in your country due to geographic restrictions.
#10. Mix and Match
ted talks, hd, this month, longThe best part about YouTube search is that you combine multiple search operators with commas and apply them all to your query (much like the Boolean AND operator). The above example will help use find all TED talks that have recently been uploaded to YouTube.
Wednesday, June 1, 2011
check internet connectivity using c#
using System ;
using System.Runtime ;
using System.Runtime.InteropServices ;
public class InternetClass
{
//Creating the extern function for checking internet connection.
[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int Description, int ReservedValue) ;
//Creating a function that uses the API function to check internet connection.
public static bool IsConnectedToInternet( )
{
int Desc ;
return InternetGetConnectedState(out Desc, 0) ;
}
}
using System.Runtime ;
using System.Runtime.InteropServices ;
public class InternetClass
{
//Creating the extern function for checking internet connection.
[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int Description, int ReservedValue) ;
//Creating a function that uses the API function to check internet connection.
public static bool IsConnectedToInternet( )
{
int Desc ;
return InternetGetConnectedState(out Desc, 0) ;
}
}
Monday, May 30, 2011
Image in C#: Save, Resize, and Convert to Binary
Sooner or later, you will find the need of handling image in your code, especially when you're working with a database. So in this article, I share with you some useful methods that I find myself using frequently. They include: saving image in a folder, getting thumbnail from the original image, converting image to binary for saving in database, and converting binary data back to image.
Save An Image
Image originalImage = Image.FromFile(imagePath);
string filePath = AppDomain.CurrentDomain.BaseDirectory + savedName;
originalImage.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);This code saves the image to the base directory of your app or website.
imagePath is the full path to the image that we need to save (e.g. "C:\Pictures\Lighthouse.jpg"), one way to get this is use an OpenFileDialog.
savedName is the name for the saved image.
Save the Image as a Thumbnail
public static void SaveImage(string imagePath, string savedName,
int width = 0, int height = 0)
{
Image originalImage = Image.FromFile(imagePath);
string filePath = AppDomain.CurrentDomain.BaseDirectory + savedName;
if (width > 0 && height > 0)
{
Image.GetThumbnailImageAbort myCallback =
new Image.GetThumbnailImageAbort(ThumbnailCallback);
Image imageToSave = originalImage.GetThumbnailImage
(width, height, myCallback, IntPtr.Zero);
imageToSave.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);
}
else
{
originalImage.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
private static bool ThumbnailCallback() { return false; }Note the parameters: int width = 0 & int height = 0. This is a C# 4.0 feature: Optional Parameters, so we can call this method like this: (assume this method is in the ImageHandling class).
// Save image as original
ImageHandling.SaveImage(@"C:\Pictures\Lighthouse.jpg", "OriginalLighthouse.jpg");
// Save image as thumbnail
ImageHandling.SaveImage(@"C:\Pictures\Lighthouse.jpg",
"ThumbnailLighthouse1.jpg", 160, 90);
// New feature: Named Parameter
ImageHandling.SaveImage(@"C:\Pictures\Lighthouse.jpg",
"ThumbnailLighthouse2.jpg", height: 90, width: 160);Resize the Image and Keep Aspect Ratio
int newWidth = originalImage.Width * percentage / 100;
int newHeight = originalImage.Height * percentage / 100;To keep the image aspect ratio, simply replace width & height parameters with percentage parameter and call the GetThumbnailImage method with our new width & height.
Convert Image to Binary
public static byte[] ImageToBinary(string imagePath)
{
FileStream fileStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[fileStream.Length];
fileStream.Read(buffer, 0, (int)fileStream.Length);
fileStream.Close();
return buffer;
}Use this method when you want to save images in your database. The column to store binary data is usually varbinary(MAX).
Convert Binary to Image
You store images in your database as binary, of course you must convert binary back to images so you can display them in your app.
public static Image BinaryToImage(System.Data.Linq.Binary binaryData)
{
if (binaryData == null) return null;
byte[] buffer = binaryData.ToArray();
MemoryStream memStream = new MemoryStream();
memStream.Write(buffer, 0, buffer.Length);
return Image.FromStream(memStream);
}You may need to add reference to System.Data.Linq. LINQ-to-SQL maps a varbinary column in your database to its relevant property as System.Data.Linq.Binary.
Save An Image
Image originalImage = Image.FromFile(imagePath);
string filePath = AppDomain.CurrentDomain.BaseDirectory + savedName;
originalImage.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);This code saves the image to the base directory of your app or website.
imagePath is the full path to the image that we need to save (e.g. "C:\Pictures\Lighthouse.jpg"), one way to get this is use an OpenFileDialog.
savedName is the name for the saved image.
Save the Image as a Thumbnail
public static void SaveImage(string imagePath, string savedName,
int width = 0, int height = 0)
{
Image originalImage = Image.FromFile(imagePath);
string filePath = AppDomain.CurrentDomain.BaseDirectory + savedName;
if (width > 0 && height > 0)
{
Image.GetThumbnailImageAbort myCallback =
new Image.GetThumbnailImageAbort(ThumbnailCallback);
Image imageToSave = originalImage.GetThumbnailImage
(width, height, myCallback, IntPtr.Zero);
imageToSave.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);
}
else
{
originalImage.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
private static bool ThumbnailCallback() { return false; }Note the parameters: int width = 0 & int height = 0. This is a C# 4.0 feature: Optional Parameters, so we can call this method like this: (assume this method is in the ImageHandling class).
// Save image as original
ImageHandling.SaveImage(@"C:\Pictures\Lighthouse.jpg", "OriginalLighthouse.jpg");
// Save image as thumbnail
ImageHandling.SaveImage(@"C:\Pictures\Lighthouse.jpg",
"ThumbnailLighthouse1.jpg", 160, 90);
// New feature: Named Parameter
ImageHandling.SaveImage(@"C:\Pictures\Lighthouse.jpg",
"ThumbnailLighthouse2.jpg", height: 90, width: 160);Resize the Image and Keep Aspect Ratio
int newWidth = originalImage.Width * percentage / 100;
int newHeight = originalImage.Height * percentage / 100;To keep the image aspect ratio, simply replace width & height parameters with percentage parameter and call the GetThumbnailImage method with our new width & height.
Convert Image to Binary
public static byte[] ImageToBinary(string imagePath)
{
FileStream fileStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[fileStream.Length];
fileStream.Read(buffer, 0, (int)fileStream.Length);
fileStream.Close();
return buffer;
}Use this method when you want to save images in your database. The column to store binary data is usually varbinary(MAX).
Convert Binary to Image
You store images in your database as binary, of course you must convert binary back to images so you can display them in your app.
public static Image BinaryToImage(System.Data.Linq.Binary binaryData)
{
if (binaryData == null) return null;
byte[] buffer = binaryData.ToArray();
MemoryStream memStream = new MemoryStream();
memStream.Write(buffer, 0, buffer.Length);
return Image.FromStream(memStream);
}You may need to add reference to System.Data.Linq. LINQ-to-SQL maps a varbinary column in your database to its relevant property as System.Data.Linq.Binary.
Sunday, May 29, 2011
Using Speech class in .net
Overview
Introduction
The Speech API library that we are going to use today is represented by the file sapi.dll which’s located in %windir%\System32\Speech\Common. This library is not part of the .NET BCL and it’s not even a .NET library, so we’ll use Interoperability to communicate with it (don’t worry, using Visual Studio it’s just a matter of adding a reference to the application.)
Implementation
In this example, we are going to create a Console application that reads text from the user and speaks it. To complete this example, follow these steps:
As an example, we’ll create a simple application that reads user inputs and speaks it. Follow these steps:
1.Create a new Console application.
2.Add a reference to the Microsoft Speech Object Library
3.Write the following code and run your application:
01.// C#
02.using SpeechLib;
03.static void Main()
04.{
05. Console.WriteLine("Enter the text to read:");
06. string txt = Console.ReadLine();
07. Speak(txt);
08.}
09.static void Speak(string text)
10.{
11. SpVoice voice = new SpVoiceClass();
12. voice.Speak(text, SpeechVoiceSpeakFlags.SVSFDefault);
13.}
01.' VB.NET
02.Imports SpeechLib
03.Sub Main()
04. Console.WriteLine("Enter the text to read:")
05. Dim txt As String = Console.ReadLine()
06. Speak(txt)
07.End Sub
08.Sub Speak(ByVal text As String)
09. Dim voice As New SpVoiceClass()
10. voice.Speak(text, SpeechVoiceSpeakFlags.SVSFDefault)
11.End Sub
If you are using Visual Studio 2010 and .NET 4.0 and the application failed to run because of Interop problems, try disabling Interop Type Embedding feature from the properties on the reference SpeechLib.dll.
Building Talking Strings
Next, we’ll make small modifications to the code above to provide an easy way to speak a given System.String. We’ll make use of the Extension Methods feature of LINQ to add the Speak() method created earlier to the System.String. Try the following code:
01.// C#
02.using SpeechLib;
03.static void Main()
04.{
05. Console.WriteLine("Enter the text to read:");
06. string txt = Console.ReadLine();
07. txt.Speak();
08.}
09.static void Speak(this string text)
10.{
11. SpVoice voice = new SpVoiceClass();
12. voice.Speak(text, SpeechVoiceSpeakFlags.SVSFDefault);
13.}
01.' VB.NET
02.Imports SpeechLib
03.Imports System.Runtime.CompilerServices
04.Sub Main()
05. Console.WriteLine("Enter the text to read:")
06. Dim txt As String = Console.ReadLine()
07. txt.Speak()
08.End Sub
09. _
10.Sub Speak(ByVal text As String)
11. Dim voice As New SpVoiceClass()
12. voice.Speak(text, SpeechVoiceSpeakFlags.SVSFDefault)
13.End Sub
I Love YOU ♥
Let’s make it more interesting. We are going to code a VBScript file that says “I Love YOU” when you call it. To complete this example, these steps:
1.Open Notepad.
2.Write the following code:
1.CreateObject("SAPI.SpVoice").Speak "I love YOU!"
Of course, CreateObject() is used to create a new instance of an object resides in a given library. SAPI is the name of the Speech API library stored in Windows Registry. SpVoice is the class name.
3.Save the file as ‘love.vbs’ (you can use any name you like, just preserve the vbs extension.)
4.Now open the file and listen, who is telling that he loves you!
Microsoft Speech API has many voices; two of them are Microsoft Sam (male), the default for Windows XP and Windows 2000, and Microsoft Ann (female), the default for Windows Vista and Windows 7.
Introduction
The Speech API library that we are going to use today is represented by the file sapi.dll which’s located in %windir%\System32\Speech\Common. This library is not part of the .NET BCL and it’s not even a .NET library, so we’ll use Interoperability to communicate with it (don’t worry, using Visual Studio it’s just a matter of adding a reference to the application.)
Implementation
In this example, we are going to create a Console application that reads text from the user and speaks it. To complete this example, follow these steps:
As an example, we’ll create a simple application that reads user inputs and speaks it. Follow these steps:
1.Create a new Console application.
2.Add a reference to the Microsoft Speech Object Library
3.Write the following code and run your application:
01.// C#
02.using SpeechLib;
03.static void Main()
04.{
05. Console.WriteLine("Enter the text to read:");
06. string txt = Console.ReadLine();
07. Speak(txt);
08.}
09.static void Speak(string text)
10.{
11. SpVoice voice = new SpVoiceClass();
12. voice.Speak(text, SpeechVoiceSpeakFlags.SVSFDefault);
13.}
01.' VB.NET
02.Imports SpeechLib
03.Sub Main()
04. Console.WriteLine("Enter the text to read:")
05. Dim txt As String = Console.ReadLine()
06. Speak(txt)
07.End Sub
08.Sub Speak(ByVal text As String)
09. Dim voice As New SpVoiceClass()
10. voice.Speak(text, SpeechVoiceSpeakFlags.SVSFDefault)
11.End Sub
If you are using Visual Studio 2010 and .NET 4.0 and the application failed to run because of Interop problems, try disabling Interop Type Embedding feature from the properties on the reference SpeechLib.dll.
Building Talking Strings
Next, we’ll make small modifications to the code above to provide an easy way to speak a given System.String. We’ll make use of the Extension Methods feature of LINQ to add the Speak() method created earlier to the System.String. Try the following code:
01.// C#
02.using SpeechLib;
03.static void Main()
04.{
05. Console.WriteLine("Enter the text to read:");
06. string txt = Console.ReadLine();
07. txt.Speak();
08.}
09.static void Speak(this string text)
10.{
11. SpVoice voice = new SpVoiceClass();
12. voice.Speak(text, SpeechVoiceSpeakFlags.SVSFDefault);
13.}
01.' VB.NET
02.Imports SpeechLib
03.Imports System.Runtime.CompilerServices
04.Sub Main()
05. Console.WriteLine("Enter the text to read:")
06. Dim txt As String = Console.ReadLine()
07. txt.Speak()
08.End Sub
09.
10.Sub Speak(ByVal text As String)
11. Dim voice As New SpVoiceClass()
12. voice.Speak(text, SpeechVoiceSpeakFlags.SVSFDefault)
13.End Sub
I Love YOU ♥
Let’s make it more interesting. We are going to code a VBScript file that says “I Love YOU” when you call it. To complete this example, these steps:
1.Open Notepad.
2.Write the following code:
1.CreateObject("SAPI.SpVoice").Speak "I love YOU!"
Of course, CreateObject() is used to create a new instance of an object resides in a given library. SAPI is the name of the Speech API library stored in Windows Registry. SpVoice is the class name.
3.Save the file as ‘love.vbs’ (you can use any name you like, just preserve the vbs extension.)
4.Now open the file and listen, who is telling that he loves you!
Microsoft Speech API has many voices; two of them are Microsoft Sam (male), the default for Windows XP and Windows 2000, and Microsoft Ann (female), the default for Windows Vista and Windows 7.
Generating email address images
Nowadays, you can't publish an email address anywhere without receiving a bunch of spam immediately after. Those spam web crawlers just search in every site looking for everything and anything that resembles an email address.
I very often see people use different variations of writing their email like "myname at mydomain.com" or "myname at mydomain dot com".
I don't think this covers it anymore...
The best way, in my opinion, is to create an image of the email address instead of writing it. (That's what Facebook does as well.)
I started working on a user based site, and the users' emails will be displayed throughout the site. So I created a class that will dynamically generate email address images for me so my precious users won't be so vulnerable to all the spam out there.
Here it is:
// Members //
private int _emailFontSize = 8;
private string _emailFontFamily = "Verdana";
private Brush _emailBackgroundColor = Brushes.White;
private Brush _emailFontColor = Brushes.Navy;
// Properties //
// I cut this out, just for convenience //
// Methods //
public void CreateEmailImage(string email)
{
// create the font object
Font myFont = new Font(_emailFontFamily, _emailFontSize);
// create the image object
Bitmap emailImage = new Bitmap((int)(myFont.SizeInPoints * email.Length),
myFont.Height);
Graphics imgGraphics = Graphics.FromImage((Image)emailImage);
imgGraphics.FillRectangle(_emailBackgroundColor,
new Rectangle(new Point(0, 0), emailImage.Size));
imgGraphics.DrawString(email, myFont, _emailFontColor, new PointF(0, 0));
// measure the actual size of the email string
SizeF stringSize = imgGraphics.MeasureString(email, myFont);
// crop the image we created
Bitmap finalImage = CropImage(emailImage,
new Rectangle(new Point(0, 0), new Size((int)stringSize.Width,
(int)stringSize.Height)));
// save the image to a local file
finalImage.Save(email + ".gif", ImageFormat.Gif);
}
private Bitmap CropImage(Image imgCrop, Rectangle cropArea)
{
Bitmap bmpImage = new Bitmap(cropArea.Width, cropArea.Height - 1);
Graphics bmpG = Graphics.FromImage(bmpImage);
bmpG.DrawImage(imgCrop, new Point(0, 0));
return bmpImage;
}
}
I very often see people use different variations of writing their email like "myname at mydomain.com" or "myname at mydomain dot com".
I don't think this covers it anymore...
The best way, in my opinion, is to create an image of the email address instead of writing it. (That's what Facebook does as well.)
I started working on a user based site, and the users' emails will be displayed throughout the site. So I created a class that will dynamically generate email address images for me so my precious users won't be so vulnerable to all the spam out there.
Here it is:
// Members //
private int _emailFontSize = 8;
private string _emailFontFamily = "Verdana";
private Brush _emailBackgroundColor = Brushes.White;
private Brush _emailFontColor = Brushes.Navy;
// Properties //
// I cut this out, just for convenience //
// Methods //
public void CreateEmailImage(string email)
{
// create the font object
Font myFont = new Font(_emailFontFamily, _emailFontSize);
// create the image object
Bitmap emailImage = new Bitmap((int)(myFont.SizeInPoints * email.Length),
myFont.Height);
Graphics imgGraphics = Graphics.FromImage((Image)emailImage);
imgGraphics.FillRectangle(_emailBackgroundColor,
new Rectangle(new Point(0, 0), emailImage.Size));
imgGraphics.DrawString(email, myFont, _emailFontColor, new PointF(0, 0));
// measure the actual size of the email string
SizeF stringSize = imgGraphics.MeasureString(email, myFont);
// crop the image we created
Bitmap finalImage = CropImage(emailImage,
new Rectangle(new Point(0, 0), new Size((int)stringSize.Width,
(int)stringSize.Height)));
// save the image to a local file
finalImage.Save(email + ".gif", ImageFormat.Gif);
}
private Bitmap CropImage(Image imgCrop, Rectangle cropArea)
{
Bitmap bmpImage = new Bitmap(cropArea.Width, cropArea.Height - 1);
Graphics bmpG = Graphics.FromImage(bmpImage);
bmpG.DrawImage(imgCrop, new Point(0, 0));
return bmpImage;
}
}
10 things to make your desktop database apps better
Data driven applications rely on their databases
Everyone knows that any app driven by data is much more than just the app. In most cases the app without a database doesn’t even function, or fails to function properly. If a database is an integral part of your application, then shouldn’t you be doing all you can to ensure it stays healthy and prepare for the worst case events of corruption or dead drives?
This week we have been contacted by 5 long time users who suddenly lost or corrupted their data. Two of these were end user data that is going to cost a huge amount of labor to reproduce. In all of these cases the following simple procedures would have prevented the situation entirely.
1 – Backup your databases
This seems pretty obvious, right? The database is just a file, xcopy it and make a backup. Enforce backups within your app, make it an integral part of the application. If a user accidentally deletes a huge part of their data, how can you recover it? With a backup it is pretty easy.
Example Strategy
When your app starts up make a backup of the database in a subfolder. A simple name of \backups within your application directory. If you want to get fancy you could even create a subdirectory under that for the YYYY-MM, or when you backup the database rename it DatabaseName-YYYY-MM.vdb4. Then you can easily show the user backups in the directory and let them pick one to restore.
To prevent the backups from growing without bounds, you can periodically sum up the sizes of them all and delete the oldest ones until you are under some threshold for size. I can almost guarantee you that having 100MB of disk space for backups is no big deal to most users these days. If that gives them a month of backups they will thank you immensely should something bad happen in the future.
2 – Ensure clean shutdown detection in single user apps
Have you ever had Microsoft Outlook crash on you while running? What happens when it restarts? Outlook will revalidate the PST file to ensure it is not corrupt.
Every app that has a database connection open should have some way to detect if it was shutdown clean. It is the only way you will know that the application was terminated (either by the user, a crash, or the OS).
Remember that VistaDB lives WITHIN your application. So when your app dies, so does the engine. A server system doesn’t have to worry about this issue because the server service is still the only thing ever talking to the file.
Example Strategy
I typically include at startup a check for a registry key. If the key still exists at startup then the app is either still running locally, or it was not shutdown clean during the last run. I put the clear function for the registry key as the very last thing that happens before the application exits. Not when I want to exit (you could still crash trying to shutdown cleanly), but right before the actual exit.
In a C# program you can do this in the Program Main function. Always put a try / catch block around the main running of your application, then add a finally that clears the shutdown.
If you want a great tool to help catch other application errors and report them I suggest Gibraltar Software. They have made it very easy to integrate a general purpose catch error system into almost any app.
3 – Ensure clean shutdown detection in multi user apps
Multi user apps are a little harder to track because you may not be the only one in the database at the time an app fails or is terminated (or the OS crashes, etc). You should still follow the above for detecting your actual application shutting down correctly, but you now have to add some more complex logic around the packing / cleanup case.
Example Strategy
We have deployed a fairly simple strategy by adding a System_Settings table on some projects. This settings table would include only 1 row normally, but include information about the last time a backup was made (to prevent every app from trying to backup when they startup), and whether the database had a dirty shutdown. When the dirty flag is set (from shared mode) the application then tries to open the database exclusive to pack. Depending upon your application you could be checking for this periodically within your app from other desktops and if the flag is seen release all connections for some period of time and then start trying to access the database again.
There are lots of different ways you could do this depending upon your application design. You could also put a flat file next to the database dirty.txt that every connection class checks before opening the database, etc. The important thing is to make sure that dirty shutdowns are detected and can be recovered without user intervention.
4 – Handle exceptions in your code
See the Gibraltar Software page for software to help you do this everywhere in your code. But even if you don’t use something like their software, you still need to ensure everywhere something can go wrong you handle it.
What if you run out of disk space during an insert? What if updating a row throws a concurrency exception? Ensure you handle those cases.
Example Strategy
The easiest way to do this is to encapsulate your database functions into a Data Access Layer (DAL). It does not have to be a separate assembly outside your application. Just ensure that you have a uniform way of accessing the database and can trap all errors. Log them to ensure that errors you didn’t expect can easily be reported back to you, even if the user has to go find a flat file called “Errors.txt” in the directory and email it to you, that is better than nothing.
5 – Put all objects in using() statements
So many of the Microsoft examples should show this best practice, but don’t. I personally don’t think it adds anything to the readability of the sample, and it is a best practice. So it should be shown at all times.
Basically anytime you are allocating an object that has a disposing on it you should be putting it into a using() block. This ensures that the GC is going to clean it up as fast as possible. Calling .Close() on the object and setting it to nothing or null is NOT the same thing. You have to call .Close(), .Dispose() and then make sure all references are gone.
Example Strategy
using (VistaDB.Provider.VistaDBDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
// Do something
}
}This one thing will do more to reduce your memory problems, fix phantom errors that occur, and so much more. I have fixed so many customer problems by simply adding using() around their object allocations. VistaDB is 100% managed code, if you don’t clean us up, or hold references to us, the objects can be pinned in RAM a very long time.
6 – Use transactions only when required
Transactions are expensive, very expensive for a file based database. Don’t use them to update a single entry in a single table, or create a transaction just to run a select query. Only use them when they make sense.
Also read the Transactions can hurt performance on our blog.
7 - Encrypt only when required, do not use for password control
This one comes into play quite often from former Access programmers. Access had this concept of a password for control of opening the file by the end user in their own copy of Access. There is no need for such a concept with VistaDB. In VistaDB 4 we changed the name from password to Encryption Phrase to make it clearer that the password is being used for encryption.
Encryption takes that base phrase, adds a salt to it, and then every page is encrypted at write time, and decrypted at load time. This is quite expensive (30% or more overhead), and if your database becomes corrupt we have no way to recover encrypted data (would sort of defeat the purpose of encryption).
You can turn on encryption for the database, and then turn it off for certain tables if you only need a single table encrypted. But this still leaves all the headers on disk encrypted, and cannot be recovered.
8 – Debug with a clean copy
Don’t debug against a production database (ever!). Especially running tests like NUnit you always want to start with a known state. The easiest way to do this is to put a pre-populated database in the application directory, and set the option in Visual Studio to Copy it to the output directory always. That way at each build you have a clean database in your debugging directory.
This is probably the #1 way people corrupt their databases. Stopping and killing the engine while doing lots of activity is eventually going to cause a corruption. Try to take SQL Server and kill it every time you stop debugging, I guarantee that you will end up with a bad database after enough iterations.
9 – Ensure regular maintenance of databases
Create a regular maintenance cycle within your app. The app could do this weekly, monthly, or based upon some internal defined “usage” case. If you know each run of your app can generate 10% turn over of data, then you should pack every 10 runs to keep the database at it’s smallest size and optimal format.
Example Strategy
Add a SYSTEM_MAINTENANCE table to your database that only has one row. LASTPACKED DateTime. Just that one field will help you determine when the database was last cleaned up. You could allow the user to do it, or prompt them, or do it in the background if you know you are at a low point for user activity.
The import thing is to have a regular plan for maintaining the database. SQL Server has these maintenance plans built in to perform index rebuilds, etc at periodic intervals. We don’t have that ability because we are only running when you are running, and we never know how long that run will last.
10 – Prepare for regular updates to components
Have a way to deploy updates to your users. You will eventually run into a bug that all your users need to avoid, or updated components from a vendor (like us). If you have no way to get that update out, you are going to have some unhappy users.
VistaDB updates periodically, and I am sure your other vendors do as well. We don’t put out updates for no reason. There are almost always fixes and updates in every build. You don’t have to rush to deploy a new major or minor, but builds within your major.minor should be considered required maintenance updates.
Sometimes customers contact us with problems from VistaDB 3.0 builds that they have never updated. Sorry, we publish regular updates, put them on the site, list them in RSS feeds, blog posts, etc. There are plenty of ways to see and get the updates. If you are running VistaDB 3.5 and are still using the initial builds you are doing yourself a disservice by not getting the more recent builds.
Any vendor product you are using that has not been updated in 12+ months is either dead (no new development), obsolete, or very trivial in nature.
Example Strategy
Pick a date (Microsoft uses the first Tuesday of the month) to go visit all your vendors. See if they have updates, read through the release notes. Plan to integrate and test them with your next build. If any of the updates from vendors are critical, then you have a critical update to perform as well.
Make sure you have a way to get updates to users. You don’t have to write all this yourself, Tarma Installer provides a very simple way to get web updates into your applications without writing complicated setup and download scripts.
Everyone knows that any app driven by data is much more than just the app. In most cases the app without a database doesn’t even function, or fails to function properly. If a database is an integral part of your application, then shouldn’t you be doing all you can to ensure it stays healthy and prepare for the worst case events of corruption or dead drives?
This week we have been contacted by 5 long time users who suddenly lost or corrupted their data. Two of these were end user data that is going to cost a huge amount of labor to reproduce. In all of these cases the following simple procedures would have prevented the situation entirely.
1 – Backup your databases
This seems pretty obvious, right? The database is just a file, xcopy it and make a backup. Enforce backups within your app, make it an integral part of the application. If a user accidentally deletes a huge part of their data, how can you recover it? With a backup it is pretty easy.
Example Strategy
When your app starts up make a backup of the database in a subfolder. A simple name of \backups within your application directory. If you want to get fancy you could even create a subdirectory under that for the YYYY-MM, or when you backup the database rename it DatabaseName-YYYY-MM.vdb4. Then you can easily show the user backups in the directory and let them pick one to restore.
To prevent the backups from growing without bounds, you can periodically sum up the sizes of them all and delete the oldest ones until you are under some threshold for size. I can almost guarantee you that having 100MB of disk space for backups is no big deal to most users these days. If that gives them a month of backups they will thank you immensely should something bad happen in the future.
2 – Ensure clean shutdown detection in single user apps
Have you ever had Microsoft Outlook crash on you while running? What happens when it restarts? Outlook will revalidate the PST file to ensure it is not corrupt.
Every app that has a database connection open should have some way to detect if it was shutdown clean. It is the only way you will know that the application was terminated (either by the user, a crash, or the OS).
Remember that VistaDB lives WITHIN your application. So when your app dies, so does the engine. A server system doesn’t have to worry about this issue because the server service is still the only thing ever talking to the file.
Example Strategy
I typically include at startup a check for a registry key. If the key still exists at startup then the app is either still running locally, or it was not shutdown clean during the last run. I put the clear function for the registry key as the very last thing that happens before the application exits. Not when I want to exit (you could still crash trying to shutdown cleanly), but right before the actual exit.
In a C# program you can do this in the Program Main function. Always put a try / catch block around the main running of your application, then add a finally that clears the shutdown.
If you want a great tool to help catch other application errors and report them I suggest Gibraltar Software. They have made it very easy to integrate a general purpose catch error system into almost any app.
3 – Ensure clean shutdown detection in multi user apps
Multi user apps are a little harder to track because you may not be the only one in the database at the time an app fails or is terminated (or the OS crashes, etc). You should still follow the above for detecting your actual application shutting down correctly, but you now have to add some more complex logic around the packing / cleanup case.
Example Strategy
We have deployed a fairly simple strategy by adding a System_Settings table on some projects. This settings table would include only 1 row normally, but include information about the last time a backup was made (to prevent every app from trying to backup when they startup), and whether the database had a dirty shutdown. When the dirty flag is set (from shared mode) the application then tries to open the database exclusive to pack. Depending upon your application you could be checking for this periodically within your app from other desktops and if the flag is seen release all connections for some period of time and then start trying to access the database again.
There are lots of different ways you could do this depending upon your application design. You could also put a flat file next to the database dirty.txt that every connection class checks before opening the database, etc. The important thing is to make sure that dirty shutdowns are detected and can be recovered without user intervention.
4 – Handle exceptions in your code
See the Gibraltar Software page for software to help you do this everywhere in your code. But even if you don’t use something like their software, you still need to ensure everywhere something can go wrong you handle it.
What if you run out of disk space during an insert? What if updating a row throws a concurrency exception? Ensure you handle those cases.
Example Strategy
The easiest way to do this is to encapsulate your database functions into a Data Access Layer (DAL). It does not have to be a separate assembly outside your application. Just ensure that you have a uniform way of accessing the database and can trap all errors. Log them to ensure that errors you didn’t expect can easily be reported back to you, even if the user has to go find a flat file called “Errors.txt” in the directory and email it to you, that is better than nothing.
5 – Put all objects in using() statements
So many of the Microsoft examples should show this best practice, but don’t. I personally don’t think it adds anything to the readability of the sample, and it is a best practice. So it should be shown at all times.
Basically anytime you are allocating an object that has a disposing on it you should be putting it into a using() block. This ensures that the GC is going to clean it up as fast as possible. Calling .Close() on the object and setting it to nothing or null is NOT the same thing. You have to call .Close(), .Dispose() and then make sure all references are gone.
Example Strategy
using (VistaDB.Provider.VistaDBDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
// Do something
}
}This one thing will do more to reduce your memory problems, fix phantom errors that occur, and so much more. I have fixed so many customer problems by simply adding using() around their object allocations. VistaDB is 100% managed code, if you don’t clean us up, or hold references to us, the objects can be pinned in RAM a very long time.
6 – Use transactions only when required
Transactions are expensive, very expensive for a file based database. Don’t use them to update a single entry in a single table, or create a transaction just to run a select query. Only use them when they make sense.
Also read the Transactions can hurt performance on our blog.
7 - Encrypt only when required, do not use for password control
This one comes into play quite often from former Access programmers. Access had this concept of a password for control of opening the file by the end user in their own copy of Access. There is no need for such a concept with VistaDB. In VistaDB 4 we changed the name from password to Encryption Phrase to make it clearer that the password is being used for encryption.
Encryption takes that base phrase, adds a salt to it, and then every page is encrypted at write time, and decrypted at load time. This is quite expensive (30% or more overhead), and if your database becomes corrupt we have no way to recover encrypted data (would sort of defeat the purpose of encryption).
You can turn on encryption for the database, and then turn it off for certain tables if you only need a single table encrypted. But this still leaves all the headers on disk encrypted, and cannot be recovered.
8 – Debug with a clean copy
Don’t debug against a production database (ever!). Especially running tests like NUnit you always want to start with a known state. The easiest way to do this is to put a pre-populated database in the application directory, and set the option in Visual Studio to Copy it to the output directory always. That way at each build you have a clean database in your debugging directory.
This is probably the #1 way people corrupt their databases. Stopping and killing the engine while doing lots of activity is eventually going to cause a corruption. Try to take SQL Server and kill it every time you stop debugging, I guarantee that you will end up with a bad database after enough iterations.
9 – Ensure regular maintenance of databases
Create a regular maintenance cycle within your app. The app could do this weekly, monthly, or based upon some internal defined “usage” case. If you know each run of your app can generate 10% turn over of data, then you should pack every 10 runs to keep the database at it’s smallest size and optimal format.
Example Strategy
Add a SYSTEM_MAINTENANCE table to your database that only has one row. LASTPACKED DateTime. Just that one field will help you determine when the database was last cleaned up. You could allow the user to do it, or prompt them, or do it in the background if you know you are at a low point for user activity.
The import thing is to have a regular plan for maintaining the database. SQL Server has these maintenance plans built in to perform index rebuilds, etc at periodic intervals. We don’t have that ability because we are only running when you are running, and we never know how long that run will last.
10 – Prepare for regular updates to components
Have a way to deploy updates to your users. You will eventually run into a bug that all your users need to avoid, or updated components from a vendor (like us). If you have no way to get that update out, you are going to have some unhappy users.
VistaDB updates periodically, and I am sure your other vendors do as well. We don’t put out updates for no reason. There are almost always fixes and updates in every build. You don’t have to rush to deploy a new major or minor, but builds within your major.minor should be considered required maintenance updates.
Sometimes customers contact us with problems from VistaDB 3.0 builds that they have never updated. Sorry, we publish regular updates, put them on the site, list them in RSS feeds, blog posts, etc. There are plenty of ways to see and get the updates. If you are running VistaDB 3.5 and are still using the initial builds you are doing yourself a disservice by not getting the more recent builds.
Any vendor product you are using that has not been updated in 12+ months is either dead (no new development), obsolete, or very trivial in nature.
Example Strategy
Pick a date (Microsoft uses the first Tuesday of the month) to go visit all your vendors. See if they have updates, read through the release notes. Plan to integrate and test them with your next build. If any of the updates from vendors are critical, then you have a critical update to perform as well.
Make sure you have a way to get updates to users. You don’t have to write all this yourself, Tarma Installer provides a very simple way to get web updates into your applications without writing complicated setup and download scripts.
Get File name from URL Path - ASP Classic
The following VBScript function can be used in an ASP legacy application to extract the file name from a request.
public function GetFileName()
dim files, url, segments
'get then current url from the server variables
url = Request.ServerVariables("path_info")
segments = split(url,"/")
'read the last segment
url = segments(ubound(segments))
GetFileName = url
end function
public function GetFileName()
dim files, url, segments
'get then current url from the server variables
url = Request.ServerVariables("path_info")
segments = split(url,"/")
'read the last segment
url = segments(ubound(segments))
GetFileName = url
end function
Subscribe to:
Posts (Atom)