StackOverflow Label

Using Source Maps with CSS

StackOverflow user Rob had a problem inspecting his SASS stylesheets after having them preprocessed by Codekit.

Having set the Output Style to "Compressed", the resulting CSS stylesheets were optimized and minified, making it almost impossible to trace the CSS back to the original SASS files.

Checking the Create a Source Map setting allowed him to help Google Chrome DevTools map the compiled CSS to the original SASS files, using a .map file, that the browser automatically uses. The principle of Source Maps is well known for JavaScript developers, but most people don't know that it is possible for CSS preprocessors too.

More information is available in the Codekit documentation for SASS.

Posted by Anders Tornblad on Category CSS Labels
Tweet this

Converting from Type to SqlDbType

StackOverflow user Simone Salvo asked how to do a smart conversion between .Net System.Type and System.Data.SqlDbType, which is not really a trivial task.

For my answer, I wrote the following somewhat naïve code:

public class SqlHelper
{
    private static Dictionary<Type, SqlDbType> typeMap;

    // Create and populate the dictionary in the static constructor
    static SqlHelper()
    {
        typeMap = new Dictionary<Type, SqlDbType>();

        typeMap[typeof(string)]         = SqlDbType.NVarChar;
        typeMap[typeof(char[])]         = SqlDbType.NVarChar;
        typeMap[typeof(byte)]           = SqlDbType.TinyInt;
        typeMap[typeof(short)]          = SqlDbType.SmallInt;
        typeMap[typeof(int)]            = SqlDbType.Int;
        typeMap[typeof(long)]           = SqlDbType.BigInt;
        typeMap[typeof(byte[])]         = SqlDbType.Image;
        typeMap[typeof(bool)]           = SqlDbType.Bit;
        typeMap[typeof(DateTime)]       = SqlDbType.DateTime2;
        typeMap[typeof(DateTimeOffset)] = SqlDbType.DateTimeOffset;
        typeMap[typeof(decimal)]        = SqlDbType.Money;
        typeMap[typeof(float)]          = SqlDbType.Real;
        typeMap[typeof(double)]         = SqlDbType.Float;
        typeMap[typeof(TimeSpan)]       = SqlDbType.Time;
        /* ... and so on ... */
    }

    // Non-generic argument-based method
    public static SqlDbType GetDbType(Type giveType)
    {
        if (typeMap.ContainsKey(giveType))
        {
            return typeMap[giveType];
        }

        throw new ArgumentException($"{giveType.FullName} is not a supported .NET class");
    }

    // Generic version
    public static SqlDbType GetDbType<T>()
    {
        return GetDbType(typeof(T));
    }
}

Caveat

The above code works fine in most cases, but comes with some problems:

  • How do you pick the correct SqlDbType value for strings? It depends on how you are using/storing that string in the database and in your application's business logic. The alternatives are:
    • Char: Fixed-length non-Unicode string of no more than 8 000 characters
    • NChar: Fixed-length Unicode string of no more than 8 000 characters
    • VarChar: Variable-length non-Unicode string of no more than 8 000 characters
    • NVarChar: Variable-length Unicode string of no more than 8 000 characters
    • Text: Non-Unicode stream of no more than 2 147 483 647 characters
    • NText: Unicode stream of no more than 1 073 741 823 characters
    • Xml: SQL Server native XML data type
  • How do you pick the correct value for blobs? There are a few alternatives there too:
    • Binary: Fixed-length stream of no more than 8 000 bytes
    • VarBinary: Variable-length stream of no more than 8 000 bytes
    • Image: Variable-length stream of no more than 2 147 483 647 bytes
  • Also for dates or timestamps there are a few different ways to go:
    • Date: Dates from 1 AD to 9999 without time of day
    • DateTime: Timestamps from 1753 to 9999 with 10/3 ms precision
    • DateTime2: Timestamps from 1 AD to 9999 with 100 ns precision
    • SmallDateTime: Timestamps from 1900 to 2079 with one minute precision
    • DateTimeOffset: Timestamps from 1 AD to 9999 with 100 ns precision, including time zone information

The best thing would almost always be to let some ORM tool do the heavy lifting.

Posted by Anders Tornblad on Category C# Labels
Tweet this

Finding the right namespace

Object Browser StackOverflow user graham added a reference to a third-party DLL called ServiceProvider.dll, but couldn't figure out which using directive to use to access the types made available in that DLL.

Most times, the DLL is named after the default namespace, which would suggest that a simple using ServiceProvider; should help, but that didn't work. When using closed-source SDKs that you purchase licenses for from some company, it is pretty common to find that their namespaces are named after the company itself. In this case, the root of the namespace hierarchy was Avaya, after the company.

When you double-click the reference in the Solution Explorer, the Object Browser opens up with the double-clicked referenced assembly pre-selected. All you have to do then is to expand the selected row to see all namespaces included in the dll file.

Posted by Anders Tornblad on Category Tools Labels
Tweet this

JavaScript countdown using localStorage

New StackOverflow user Pankaj Badera asked how to create a simple JavaScript timer that would survive reboots of the user's computer.

For the specific question, this is not a good idea, because it seems as if the problem needs to deal with some sort of timing rules (school assignment deadlines, maybe?), in which case a server-side solution is a must. However, the technical aspects is pretty intriguing. As it turns out, I have already faced this problem before, when building Tajmkiper, which handles all of its timing client-side.

In principal, you can start any type of countdown, or "countup", allowing the counter to continue between browser and computer restarts, by simply recording the current time for when an event starts, and then continuously checking the difference between that saved value and the current time of a later event.

In Tajmkiper, this is done for many projects at the same time, but the principle is the same. In the case of this StackOverflow question, there is only one timer. Also, Tajmkiper is meant to be a tool for the user, and not for keeping track of (from the browser's perspective) externally checked rules like deadlines, so a solution involving local storage is fine.

My answer looks like this:

(function() {
    var started = localStorage['started'];

    if (started) {
        // This is not the first time the user opens this file
        // How long has it been?

        var diff = Date.now() - started;

        if (diff >= 1000 * 60 * 60 * 24 * 7) {
            // At least one week has passed. Do something here.
        } else {
            // Less than a week has passed. Do something else here.
        }
    } else {
        // This is the first time the user opens this file

        localStorage['started'] = Date.now();

        // Do something else here to welcome the user...
    }
})();

For my project time clock, this happens every time you select a different project. I combine this with keeping track of how much time has been clocked total.

Posted by Anders Tornblad on Category JavaScript Labels
Tweet this

Formatting a truncated float in JavaScript

StackOverflow user nips asked how to format a floating point number in JavaScript, truncating the value instead of rounding it.

According to the question, this was the desired result:

  • The value 12.999 must be displayed as 12.99
  • The value 14 must be displayed as 14.00

The developer.mozilla.org page gives a thorough example of how to perform decimal rounding correctly, avoiding any rounding errors in the process. For this question, however, a simple multiplication-division pair is surely good enough:

// truncate-and-format.js

// Step by step
var multiplied = value * 100;
var truncated  = Math.floor(multiplied);
var divided    = truncated * 0.01;
var output     = divided.toFixed(2);

// One-liner version
var output = (Math.floor(value * 100) * 0.01).toFixed(2);

The above code performs the following steps, in order:

  • Value is multiplied by 100
    • 12.999 => 1299.9
    • 14 => 1400
  • Value is truncated using the Math.floor function
    • 1299.9 => 1299
    • 1400 => 1400
  • Value is multiplied by 0.01
    • 1299 => 12.99
    • 1400 => 14
  • Value is formatted for printing using two decimal places using the Number.prototype.toFixed function
    • 12.99 => "12.99"
    • 14 => "14.00"

Most languages do have functions called round, ceil, floor or similar ones, but almost all of them round to the nearest integer, so the multiply-round-divide chain (or divide-round-multiply for rounding to tens, hundreds, thousands...) is a good pattern to know.

In JavaScript there is no float datatype like in a lot of other languages, but the Number type is used for both integers and floating point numbers. Internally, numbers are just 64 bit floating point numbers (source: ecma262-6.com), conforming to the IEEE 754 standard. So when dealing with numbers in JavaScript, you always need to take floating point precision into consideration!

Posted by Anders Tornblad on Category JavaScript Labels
Tweet this