Tuesday, July 26, 2016

I am migrating off of Blogger and moving to Wordpress

Hello readers,

I will be migrating my blog from Blogger to Wordpress. It is going to be a medium sized project for me to do so I am not sure when it will actually be complete. The good news is this blog will stay intact until I am finished (and maybe after?). Any popular posts will be forwarded to my WordPress site. I am going to try to forward everything properly, but I don't want to break existing links out on the web either - because I am a nice guy and I am thinking of you :)

Here is the new WordPress URL:

I decided to move off of blogger because I need more freedom to do what I need to do. I want to be able to provide files and possibly even write more complex things directly on the site in PHP or whatever. WordPress is far more capable than Blogger is, I have been evaluating it for a while now and getting more familiar. It truly is an amazing CMS that is easy to work with. Plugins galore for just about everything.

Thanks,

Eli

Saturday, July 23, 2016

How to bake Jachnun

I'm not an expert on this

I am not an expert on doing this, but I did it this weekend and it came out great. I did not make my Jachnun from scratch, I purchased it frozen from a kosher store and it is very good. I am just surprised at the lack of instructions on how to bake Jachnun so I am posting it here for people to find easily. Understand there are MANY ways to do this, I am saying this method worked just fine for me.

This guy sounds like an expert

This guy looks and sounds like he knows what he is doing so you can watch this video if you want instead:
https://www.youtube.com/watch?v=8d9S6bkanig

I'm lazy, so this is what I did instead

I took a different route because I am lazy and don't want to be bothered with all of the inane details of turning it into a meal which I don't want to do. I eat Jachnun as a dessert with honey - because it is delicious and I love it.

Okay on to the steps!

  1. Get an oven safe pot that has a cover. If you have a cast iron pot or dutch oven - then AWESOME that will work. There actually is a dedicated Jachnun pot for this, but I found my enamel coated dutch oven to work beautifully.
  2. Get some butter and butter the hell out of the inside of the container. 
    1. But I want it to be parve! If you keep kosher and you want it to be parve, then use margarine instead. You should then margarine the hell out of the inside of the container instead.
  3. Unwrap the Jachnun (it is usually wrapped in plastic) and place it inside of the container. It is okay if they are touching, just make sure they are all facing the same way.
  4. Place the cover on your container
  5. Set your container on the bottom rack of your oven
  6. Set your oven's temperature to 200 *F
  7. Let your Jachnun bake for 12 hours. That is not a typo - Twelve Hours. I'm serious.
    1. It is recommended to do this before bed so that you can wake up and take it out of the oven.
  8. After waiting 12 hours - you can take your Jachnun out of the oven
  9. You will see a pool of oil/butter - that's okay
  10. Let your Jachnun cool, it is going to reabsorb all of that oil/butter - that's what makes it yummy
  11. Use a pair of tongs to pick up your Jachnun
  12. Get a flat plate
  13. Place Jachnun on plate and cut it into nice chunks
  14. Get some honey and pour a dollop on your plate
  15. Dip chunk of Jachnun on plate
  16. Place in mouth
  17. Chew
  18. Have foodgasm
  19. Repeat steps 16 through 19 until you run out of Jachnun, if you run out move on to the next step
  20. Feel very sick, but happy
  21. Get on treadmill and work off the gagillion calories you just ingested 
http://www.explosm.net/

MVC CSHTML partial view loses all syntax highlighting/color during rename operation; then copy, cut or paste operations cause Visual Studio errors to be thrown

Obscure problem

This was a weird one and as weird problems go with Visual Studio - they always happen out of the blue and when you really really need to get work done. I was working on an MVC 5 partial view (*.cshtml) and out of nowhere all of a sudden all color was drained from the markup. I lost my syntax highlighting. The MVC editor was already very fickle, so I ignored it and I closed the file and re-opened it because that usually fixes the problem. Well... that didn't work this time. The file still didn't have its color. I needed to get work done and I can work without syntax highlighting or intellisense just fine so I attempted to cut a highlighted section of code and I was met with the following error:

Inconsistent length calculation in projection snapshot.
I have no flipping idea what that is supposed to mean which is why this error is going into my "Application errors hall of shame". Therefore as usual, you click OK, you know - because you are presented with such a huge list of alternatives and you try again. Well trying again gave me this error instead:

Attempted TextBuffer edit operation while another edit is in progress.
I understand this error a little clearer, but honestly it doesn't matter because it is a symptom of the overall problem. Long story short, "Something broke". This message in particular is just saying that you already tried to copy, cut or paste something already and that operation didn't complete so you cannot start a new one. Hence the TextBuffer is in use, you cannot edit it while in use.

Obscure solution

At this point I thought Visual Studio was broken. I should have known better because other CSHTML files were just fine. I am going to break this down in what to do and what not to do:

Don't do these things because they are unnecessary in this situation and won't help

  1. Don't reinstall Visual Studio
  2. Don't repair Visual Studio
  3. Don't run "devenv.exe /resetsettings"
  4. Don't delete your solutions ".vs" hidden folder
  5. Don't delete the contents of your ComponentModelCache folder: "%appdatalocal%/Microsoft/VisualStudio/14.0/"  -  This is assuming VS2015
  6. You can and should install Visual Studio updates, but it won't help with you with this problem

Do this instead

Hopefully this solves your problem, as all weird problems I cannot predict that we are having the same problem. Anyhow - all you have to do is inspect your problem *.cshtml file for something that looks like the following snippet below. This is just an example of actual code I was working with. Please understand this is a subsection and this code isn't supposed to make sense.

Please click the image to view it clearly, it is a little large.
What happened? My file was corrupted during a keyboard operation. I am not certain, but I believe the corruption occurred when I attempted to do a rename operation on a variable on the page using F2. This is a bug in Visual Studio for sure because the MVC view editor is very buggy. It is constantly crashing Visual Studio for me. Please draw your attention to the lines that start with a hashtag "#" - I didn't put those there. VS put them there when the rename operation failed horribly and corrupted the file. To make matters worse, I lost the bottom half of my file. Thank goodness for source control, I was able to recover everything just fine.

#line default
#line hidden

#line 72 "C:\Dev\this_is_the_path_to_this_view\Expanded.cshtml"
 __o = val;


#line default
 rline hidden
r
#line 73 "C:\Dev\this_is_the_path_to_this_view\Expanded.cshtml"
r

Therefore in order to fix this, you have to get rid of all of the corrupted syntax and lines that I am pointing out above. Just be aware that you might have lost the bottom half of your file too. You might want to get forced latest from source control or proceed at your own risk after fixing your file. If the syntax highlighting comes back and you can copy, cut and paste freely again - then the file is fixed.

A very simplistic explanation of events in C#

Introduction

If you just want to see the code involved, go to the end of this article.

I am really writing this for myself because on the rare occasion that I have to rely on events for something, I am constantly forgetting how to write my own events. I don't write my own events that often because the type of work that I do just doesn't call for it most of the time. Events are great, but just like any other tool, I use them when I need them. My most recent scenario was a very complicated 3rd party ascx control was doing all kinds of crazy stuff after an aspx page has loaded. I needed the end result produced by the control to drive something else on the page. This was the effort to produce an optimization because the same end result was being generated twice which is just plain wasteful and goes against DRY which is ALWAYS a NO-NO! Therefore created an event to be fired off after the 3rd party control was finished doing all of the crazy stuff it was doing. I used the provided result to drive the aforementioned other stuff on the page. It worked great.

High-level view

When you need to create a new event, it is usually on the spot and in a rush - especially when you haven't written one in a while. Therefore here are some simple things to remember when encountering this situation:
  1. Your parent object needs a reference to its child object that will be raising the event. Without this, you cannot magically catch the event - aside from bubble events, but let's not get into that. Bubble events are something you deal with specifically in ASP.NET with pages being the parent and user controls being the child. However, I want to focus on creating custom events.
  2. After your parent object has a reference to its child object, you need to explicitly state that you are listening for an event to be raised from the child object by registering a method handle, located in the parent object, with an event handler delegate provided by the child object reference.
  3. The previous step leads into this step - you need to define your method.

Very simple relatable example

A mother has a baby. The mother is the parent object and the baby is the child object. The mother is explicitly listening to the baby always. The baby provides a crying event that it can raise for any reason. The mother is registered with this event and knows how to handle it when raised. If the mother hears someone else's baby crying event, they probably won't be as inclined to go check it out because it isn't their kid.

Writing your custom event

In C# there are three components that you need to provide in order to get started with events. These components must all reside inside of the child object (which is relative, but for argument's sake, let's say it is a child object).
  1. Delegate
  2. Event
  3. Boilerplate raise method (optional, but nice to have)
  4. Optional event arguments class if required, to be declared outside of the child object for the sake of reusability

1. Delegate

public delegate void CryHandler(object sender, CryEventArgs e);

The best way to understand what this is and why you need it is to first understand what a delegate is and how you would use it. Delegates are best thought of as something that executes when the time is right.

Example:
Imagine that you are calling customer service for a company that has notoriously long hold times. Recently, some companies that have been implementing a callback service for when it is your turn to finally speak to someone instead of just waiting for an indeterminate amount of time. You provide a phone number to the callback service so that when it is your turn, you get a callback. In this example you are the parent object, your phone number is the delegate, the callback service is the event that is raised when it is your turn to be helped and the customer service department is the child object. You are listening for a phone call and the customer service callback service needs to call you. It finds you again by using the phone number you provided.

2. Event

public event CryHandler Cry;

You can't have an event without a delegate. Your event, "Cry", is what is exposed in order for the parent who is listening for the raised event to register it's method handle for the delegate to call when the time is right.

3. Raising your event

private void RaiseCryEvent(CryEventArgs e)
{
    if(Cry != null)
        Cry(this, e);
}

This is the code I use for raising events. This is not a hard and fast rule to have this method because, just like everything in programming, it depends on what you are doing. This method implies that you will raise this event from inside of the object that exposes the event to begin with.

One of the most confusing things about this code is, "Why are we checking for null?" Simply put, if a method handle was not provided for the delegate to call back, then the reference will be null. If we do not check for null, then we risk encountering a NullReferenceException.

4. Event arguments class

public class CryEventArgs : EventArgs
{
    //Wouldn't it be nice to know why the baby is crying?
    public string Reason { get; set; }
}

This is an optional step because it depends on what you are doing/designing. The question to ask yourself here is "Do I need to send back data?" 
  • If the answer is no, then you can just use the EventArgs class because you won't care about what is being sent back. This is okay sometimes if all you are looking for is the callback. Think of a click event on a page, 99.99% of the time, you just care that someone pressed the button, you are not looking at the sender object or the EventArgs e. 
  • If the answer is yes, then you should really create a new Event Arguments class because it just makes life easier. Make things explicit to avoid depending on casting, boxing and unboxing which is what you would need to do if you just use the stock EventArgs class. Don't do that, it is very bad practice, lazy and pointless.

Using your Custom Event

In order to use your custom event, like I pointed out earlier you need an object reference to your target child object. For the sake of argument, let's continue with the same mother and baby example.
public class Mother
{
 //Child object reference
 Baby _billy;

 public Mother()
 {
  //Child object
  _billy = new Baby();

  //Registering for a call back or listening for the baby to cry
  _billy.Cry += Billy_CryHandler;

  //Put the baby to sleep, the baby will wake up eventually
  _billy.Sleep();
 }

 //When the baby is awoken, you need to ask the baby 
 //why it woke up and put it back to sleep
 private void Billy_CryHandler(object sender, CryEventArgs e)
 {
  //The reason was passed over using our custom event argument object
  Console.WriteLine("Why are you awake Billy? - " + e.Reason + "\n");
  
  Console.WriteLine("Billy, go back to sleep!\n");

  //Put the baby back to bed
  _billy.Sleep();
 }
}

public class Baby
{
 //The model method that will be called when the event is raised "Call me back at"
 public delegate void CryHandler(object sender, CryEventArgs e);
 
 //The way that you can register for a call back
 public event CryHandler Cry;

 Random _r;

 public Baby()
 {
  _r = new Random();
 }

 public void Sleep()
 {
  //Get a value between 0 and 10 - which is indeterminate enough for this example
  int sleep = _r.Next(10);

  //Announce that the baby will be put back to bed
  Console.WriteLine("Baby will be sleeping for " + sleep + " seconds.\n");

  //Long running process
  System.Threading.Thread.Sleep(sleep * 1000);

  //Callback when the baby wakes up
  RaiseCryEvent(new CryEventArgs() { Reason = "I pissed myself again..." });
 }

 private void RaiseCryEvent(CryEventArgs e)
 {
  //This is syntactic sugar - a one liner that replaces 
  //the if statement in the prior example
  Cry?.Invoke(this, e);
 }
}

Sunday, July 17, 2016

Relative paths regarding images

The problem

I run into this problem on occasion and unfortunately it is more complicated than it sounds. Really I don't understand why the frameworks responsible make this so damn complicated. I am basically going on a guess here and I think it is a combination between the web servers (not so much) and web browser engines along with the W3C's HTML standards. The problem I am driving up to is using relative paths for statically located images and other resources on your website. 

Really this comes down to the folder structure of your site, but I don't think the folder structure of your site should have to suffer from this problem. I think you should be allowed to have as many nested folders as you want and come up with crazy structures - it still doesn't explain why in all the years of web this problem has not be solved in a simple way.

Everything is best explained with an example.

Assumptions

  • For argument's sake let's focus on images and forget about JS and CSS for now. 
  • Let's call the root of my site http://www.CoolSite.com/
  • Let's say that the root of my site is physically located at C:\CoolSite\
  • Let's say I have a folder where I keep all of my images, 
    • Physically located here: C:\CoolSite\images\
    • Virtually located here: http://www.CoolSite.com/images/
  • I have an image in the images folder named "loading.gif":
    • C:\CoolSite\images\loading.gif
    • http://www.CoolSite.com/images/loading.gif
  • I have a page that references loading.gif at the root of my site
    • C:\CoolSite\test.htm
    • http://www.CoolSite.com/test.htm
As is - the above works perfectly fine. However, someone comes along and says: 
I need to use loading.gif in a new feature that is going to be located in a different folder called "FakeDir1".

Nested directory one

  • FakeDir1, contains its own test.htm which references loading.gif
    • C:\CoolSite\FakeDir1\test.htm
    • http://www.CoolSite.com/FakeDir1/test.htm
Well now... this causes a problem. Usually people think it is just fine to use relative pathing, but I beg to differ. Microsoft 95% solved this problem by introducing a special MS convention that uses the tilde character. I am not going to get into that, because it is not relevant to plain, simple, HTML. Therefore how does one normally handle this right off the bat? Like so:
  • FakeDir1, contains its own test.htm which references loading.gif
    • C:\CoolSite\FakeDir1\test.htm
    • http://www.CoolSite.com/FakeDir1/test.htm
    • For your image source attribute: ../images/loading.gif
And thus, this reads "Go down one directory relative to where I am right now and then back up into a folder that is hopefully located there called images and you shall land upon loading.gif" - oh great, this solves the problem... but then someone comes along and says:
"I need to use loading.gif in a new feature that is going to be located inside of FakeDire1 named "FakeDir2".

Nested directory two

Sigh... okay... so this forces us one more time to do this:
  • FakeDir2, contains its own test.htm which references loading.gif
    • C:\CoolSite\FakeDir1\FakeDir2\test.htm
    • http://www.CoolSite.com/FakeDir1/FakeDir2/test.htm
    • For your image source attribute: ../../images/loading.gif
Oh wonderful, there is a recurring pattern which is not being taken care of automatically - this is never good. It means copy/paste and creating brittle structures. Below is a visual representation of what was just done. Ignore the URL, it is the same idea as what was explained above, I was explaining this to a coworker of mine at work.

Nested directory N

Root example equivalent to http://www.CoolSite.com/test.htm

http://www.CoolSite.com/FakeDir1/test.htm - up one directory

http://www.CoolSite.com/FakeDir1/FakeDir2/test.htm - up two directories

http://www.CoolSite.com/FakeDir1/FakeDir2/FakeDir3/test.htm - up three directories
If you have been following the examples from top to bottom you will notice that the top line's image source never breaks. The image always renders. You are probably thinking that - that's the way to go. Well you would be wrong again because that stops working as soon as you want to place your site inside of a virtual directory because this syntax "/images/loading.gif" reads "Go to the root of this site, locate a folder called images and find a file called loading.gif".

Therefore to be very clear the following will break this: "/images/loading.gif"

If I take the source of "http://CoolSite.com/" and point it to the following virtual directory "http://CoolSite.com/VirtualDirectory1/" then you will have the following configuration for the root page:
  • C:\CoolSite\test.htm
  • C:\CoolSite\images\loading.gif
  • http://www.CoolSite.com/VirtualDirectory1/test.htm
  • http://www.CoolSite.com/VirtualDirectory1/images/loading.gif
  • For your image source attribute: 
    • ./images/loading.gif - will work
    • /images/loading.gif - will NOT work because it will be looking here "http://www.CoolSite.com/images/loading.gif" which doesn't virtually exist

The solutions

These are the solutions I could find for this, none of them are very good, but it's what I could come up with to deal with these situations.

  1. Make sure when you are setting up your sites, you are not using Virtual Directories for your sites because then you cannot use this syntax "/images/loading.gif" for example. As indicated already above, that syntax goes to the base site. You have to ask yourself "Why am I using a virtual directory?" Usually the answer is "I don't know how to setup multiple websites on the same server." - well, I don't mean to be harsh, but that isn't an excuse - go learn how to do it. I will eventually write an article on this, but the information is readily available. Stop using Virtual Directories unless you know why you are using them.
  2. Use a media server, image server or Content Delivery Network (CDN) so that your URLs never change, then folder depth doesn't matter anymore. However, problems come with this and they are:
    1. Remember to update your content when something has changed
    2. Development can become a problem
    3. Now your content is separated from your site, this isn't generally a good idea unless you are a massive site
  3. This is a pretty bad solution, but it will work. Copy your images relative to things that need them that way the pathing doesn't matter ever. Examples:
    1. http://www.CoolSite.com/Images/loading.gif
    2. http://www.CoolSite.com/test.htm - if you use "/images/loading.gif" - this will work
    3. http://www.CoolSite.com/VirtualDirectory1/test.htm - if you use "/images/loading.gif" - this will work
    4. However, just like the CDN you have to remember to update that images folder. The way I am showing it is a clean way of doing it. A crappier way to do it is to copy the images folder into each FakeDir and update the pathing to use "./images/loading.gif" then you can make sure to update every images folder always. Scripts can accomplish this, but why go this far?

Conclusion

The point is that there are various ways to deal with this, but realistically there isn't a good way to deal with it. Your best defense is a good architecture and directory structure. Lean on a framework for help where it makes sense, but not to the point where it makes your site suffer.

Sql Server tSql: DELETE statement executes but won't delete

Problem

I ran into the most puzzling issue recently where I was executing a DELETE statement inside of a transaction among other statements inside of a stored procedure. Then the weirdest most puzzling thing happened, the statement executed, but would not delete rows. It was very bizarre. Then when the whole process was finished if I executed the statement afterwards it worked. I thought maybe it had something to do with executing inside of a transaction, so I took the statement out of the transaction and it still didn't work. The syntax you are going to see is in SQL Server 2005 format because that is what I had to support, but I was running my tests on SQL Server 2014.

Long story short, after several hours of frustration, I figured it out.

Gotcha

Before I get to the gotcha, I just want to point out that I am a Software Architect with a ton of exposure to tSql, but I am not a DBA so some of these core SQL concentric problems still allude me at times. I always appreciate these moments of absolute clarity due to epiphany, it's a good feeling. 
Moving along to the gotcha... It turns out that the tables I was working on had triggers and constraints with cascading deletes enabled. This was really causing some seemingly strange behavior during execution. Obviously there is nothing strange about the execution after I learned that these tables had these other objects buzzing away in the background during the execution of my DELETE statements.

I disabled all triggers and constraints (specifically with cascading deletes enabled) associated with the target tables and the strange behavior disappeared and the deletes actually executed. One of the strangest parts about this is that there were no triggers directly on the target tables, so I don't understand what was blocking the delete.

What was most frustrating about this experience is that I would not see an error, everything just appeared as though it executed.

Delete Example

Everything is always better with an example so here it is. Imagine you have a huge table that needs to be pruned. You are given a list of criteria, but really it boils down to batch deleting rows from a target table.

DECLARE @batchSize INT = 5000;
DECLARE @rowCount INT = 1;

WHILE @rowCount > 0
BEGIN
 DELETE TOP(@batchSize) t
 FROM dbo.Table1 t

 SET @rowCount = @@ROWCOUNT;
END

The amount being deleted is truly arbitrary, so I just chose 5K for the sake of argument. Let's say this is a special table that has a lot of things happening to it implicitly and indirectly, much like many things in the magic world of SQL engines. Some of these things are constraints and some of these things are triggers, therefore in order to successfully delete those rows above, these constraints and triggers must be temporarily disabled. This of course leads to a new host of problems such as - should you be running this in single user mode and things of that nature. The answer is yes, now how you convince your co-workers, boss and especially your DBA of this is up to you I cannot help you with this. Especially if you have to tear down replication and rebuild it. Have fun with that.

Toggling Constraints

Turns your constraints on and off for a pre-defined set of tables. The sproc following this one really isn't all that much different except for the syntax of the command being dynamically constructed. Really this is straight-forward.

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- [dbo].[sp_ToggleConstraints] 1
-- [dbo].[sp_ToggleConstraints] 0
CREATE PROCEDURE [dbo].[sp_ToggleConstraints]
(
 @isEnabled BIT
)
AS
BEGIN
 SET NOCOUNT ON;
 
 DECLARE @keywords VARCHAR(50);

 DECLARE @sqlStatements TABLE
 ( 
   EntryId INT IDENTITY(0,1)
  ,SqlStatement VARCHAR(255)
 )

 IF @isEnabled = 1
  SET @keywords = ' WITH NOCHECK CHECK CONSTRAINT '
 ELSE
  SET @keywords = ' NOCHECK CONSTRAINT '

 /* Examples: 
   Disable: ALTER TABLE dbo.[TargetTableName] NOCHECK CONSTRAINT [FK name]
   Enable : ALTER TABLE dbo.[TargetTableName] WITH CHECK CHECK CONSTRAINT [FK name]
 */

 -- Select your dynamically created SQL statements for constraints
 INSERT INTO @sqlStatements
 SELECT 
  sqlConstraint = 'ALTER TABLE dbo.' + x.TableName + @keywords + x.ConstraintName
 FROM
 (
  SELECT
    TableName = t.name
   ,ConstraintName = fk.name
  FROM [dbo].[TableTarget] att -- It's a good idea to know what you are targetting

   INNER JOIN sys.tables t 
    ON t.name = att.TableName
   INNER JOIN sys.schemas s
    ON t.schema_id = s.schema_id
     AND s.name = 'dbo'
   INNER JOIN sys.foreign_keys fk
    ON fk.parent_object_id = t.object_id
     AND fk.delete_referential_action = 1 -- Targetting constraints with cascading deletes only
  WHERE att.ToggleConstraints = 1 -- Only select tables that should have their constraints toggled
  
  -- Sometimes tables are so poorly designed that all constraints have to be toggled
  UNION SELECT
    TableName = 'ScrewedUpTable1'
   ,ConstraintName = 'ALL'
  UNION SELECT
    TableName = 'ScrewedUpTable2'
   ,ConstraintName = 'ALL'
 ) as x
 ORDER BY
  x.TableName

 --SELECT * FROM @sqlStatements
 DECLARE @i INT;
 SET @i = 0;

 DECLARE @count INT;

 SELECT @count = COUNT(1)
 FROM @sqlStatements

 DECLARE @str VARCHAR(255)

 WHILE @i < @count
 BEGIN
  SELECT 
   @str = SqlStatement
  FROM @sqlStatements
  WHERE EntryId = @i;
  
  PRINT @str

  BEGIN TRY
   EXEC(@str);
  END TRY
  BEGIN CATCH
   -- declare the variables
   DECLARE @errorNumber INT
   ,@errorSeverity INT
   ,@errorState INT
   ,@errorProcedure nvarchar(128)
   ,@errorLine INT
   ,@errorMessage nvarchar(4000)

   -- Store the values
   SET @errorNumber = ERROR_NUMBER()
   SET @errorSeverity = ERROR_SEVERITY()
   SET @errorState = ERROR_STATE()
   SET @errorProcedure = ERROR_PROCEDURE()
   SET @errorLine = ERROR_LINE()
   SET @errorMessage = ERROR_MESSAGE()
 
   -- Check the values
   SELECT
    Number = @errorNumber
   ,Severity = @errorSeverity 
   ,[State] = @errorState
   ,[Procedure] = @errorProcedure
   ,Line = @errorLine
   ,[Message] = @errorMessage

   -- Log the error
   EXEC yourLoggingSprocGoesHere_youShouldReallyHaveOnIfYouDont
    @errorNumber = @errorNumber
   ,@errorSeverity = @errorSeverity
   ,@errorState = @errorState
   ,@errorProcedure = @errorProcedure
   ,@errorLine = @errorLine
   ,@errorMessage = @errorMessage
  END CATCH

  SET @i = @i + 1;
 END
END
GO

Toggling Triggers

Turn your triggers on and off. Very much like the previous sproc.

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- [dbo].[sp_ToggleTriggers] 1
-- [dbo].[sp_ToggleTriggers] 0
CREATE PROCEDURE [dbo].[sp_ToggleTriggers]
(
 @isEnabled BIT
)
AS
BEGIN
 SET NOCOUNT ON;
 
 DECLARE @keyword VARCHAR(7);

 IF @isEnabled = 1
  SET @keyword = 'ENABLE'
 ELSE
  SET @keyword = 'DISABLE'
 
 DECLARE @sqlStatements TABLE
 ( 
   EntryId INT IDENTITY(0,1)
  ,SqlStatement VARCHAR(255)
 )

 /* Examples: 
   ENABLE  TRIGGER dbo.[triggerName] ON dbo.[targetTableName]
   DISABLE TRIGGER dbo.[triggerName] ON dbo.[targetTableName]
 */
 INSERT INTO @sqlStatements
 SELECT
  sqlTrigger = @keyword + ' TRIGGER dbo.' + g.name + ' ON dbo.' + t.name
 FROM [dbo].[TableTarget] att -- It's a good idea to know what you are targetting
  INNER JOIN sys.tables t
   ON t.name = att.TableName
  INNER JOIN sys.schemas s
   ON t.schema_id = s.schema_id
    AND s.name = 'dbo'
  INNER JOIN sys.triggers g
   ON g.parent_id = t.object_id
 WHERE g.name LIKE 'trfs%' -- You may have to filter your triggers if you use replication. Mine happen to start with "trfs"
 ORDER BY g.name

 --SELECT * FROM @sqlStatements
 DECLARE @i INT;
 SET @i = 0;

 DECLARE @count INT;

 SELECT @count = COUNT(1)
 FROM @sqlStatements

 DECLARE @str VARCHAR(255)

 WHILE @i < @count
 BEGIN
  SELECT 
   @str = SqlStatement
  FROM @sqlStatements
  WHERE EntryId = @i;
  
  PRINT @str

  BEGIN TRY
   EXEC(@str);
  END TRY
  BEGIN CATCH
   -- declare the variables
   declare @errorNumber INT
   ,@errorSeverity INT
   ,@errorState INT
   ,@errorProcedure nvarchar(128)
   ,@errorLine INT
   ,@errorMessage nvarchar(4000)

   -- Store the values
   SET @errorNumber = ERROR_NUMBER()
   SET @errorSeverity = ERROR_SEVERITY()
   SET @errorState = ERROR_STATE()
   SET @errorProcedure = ERROR_PROCEDURE()
   SET @errorLine = ERROR_LINE()
   SET @errorMessage = ERROR_MESSAGE()
 
   -- Check the values
   SELECT
    Number = @errorNumber
   ,Severity = @errorSeverity 
   ,[State] = @errorState
   ,[Procedure] = @errorProcedure
   ,Line = @errorLine
   ,[Message] = @errorMessage

   -- Log the error
   EXEC yourLoggingSprocGoesHere_youShouldReallyHaveOnIfYouDont
    @errorNumber = @errorNumber
   ,@errorSeverity = @errorSeverity
   ,@errorState = @errorState
   ,@errorProcedure = @errorProcedure
   ,@errorLine = @errorLine
   ,@errorMessage = @errorMessage
  END CATCH

  SET @i = @i + 1;
 END
END
GO

Saturday, January 16, 2016

How to get water out of your Etymotic earplugs

Eteh-wah? 


http://www.etymotic.com/er20.html

These are called Etymotic earplugs, I call them hearing savers. I have the exact pair shown above (the blue one) - you can get them for about $20 and they are totally worth getting. The use case for these earplugs is when you have to be in a noisy environment, but you still need to hear what is going on. These plugs will just lower the noise/volume by 20dB allowing you to still hear what is happening comfortably and basically crystal clear without having to worry about not being able to hear later.

These are ideal for:

  1. Concerts
  2. Clubs
  3. Loud social events with loud people or loud music blaring
These earplugs are NOT suited for:
  1. Gun ranges - use circumaural ear muffs instead such as this here.
  2. Loud machinery - such as a hammer drill, hammering metal, circular saw etc...
  3. In-laws - no amount of ear protection will help you here
The hardest thing to understand about using these earplugs is how to put them in your ear. They are slightly curved, so you need to practice putting them in. The included strings are optional to use. When you aren't using the strings, people basically don't know you are wearing them until you point it out or if they look at the side of your face. Honestly - I don't care about looks, I just want to not go deaf when I go to a concert or a loud social gathering.

Gotcha: The setup

You were cleaning your Etymotic earplugs after using them - as you should because they get pretty nasty after long use. Woops - water got inside of the plug... crap... how do you get the water out? Ambient drying will take too long or never fully dry which will render them useless and somewhat dangerous because of the possibility of mold growth.

Depending on how gunky you get your earplugs, you should consider using very mild soap to break down the ear wax and gently work it around the earplug. Then rinse thoroughly with water. If you don't hold the opening of your earplug down away from water, you will get water into your earplug.

The simple fix

This isn't a big deal if your earplug came equipped with a lanyard or string that holds on to your plugs. To get the water out of the plug:
  1. Attach your earplug to the included holder or secure it to a flexible string with tape or something. If you are taping it, make sure to tape the diaphragm end (clear plastic) leaving the opening open (silicone part), away from the tape and inline with the string.
  2. You are going to have to do this for each plug individually:
    1. Left plug: Hold the string next to the right plug and helicopter the left plug in the largest circle possible as fast as possible for less than a minute. The centripetal force will force the water out of the plug through the opening in the plug.
    2. Right plug: Do the exact same thing, this time hold the string next to the left plug...
  3. Take the plugs off of the holder (or untape it)
  4. Inspect the diaphragm to see if there is any more water, there really shouldn't be if you swung hard enough and there are no blockages in the opening or sound canal.
  5. Let the plugs air dry now, you can hang them or just lay them down - do not put them in the sun.
If this doesn't work for you, you should probably buy a new pair as instructed by the manufacturer. They recommend every 3-6 months if you use them heavily which I do not. I have had the same pair for more than 4 years now because I have only used it about 5 or 6 times - each time I am thankful for having them.