SQL Server Flatten and Unflatten

Assuming you have a table type named SingleColumnText which contains (obviously) a single column of text, named [TextValue]:

create function util.Flatten
(
    @input util.SingleColumnText readonly
    ,@delimiter nvarchar(max)
)
returns nvarchar(max)
as
begin
    declare @result nvarchar(max);
    select @result = coalesce(@result + @delimiter, '') + TextValue
    from @input
    order by PK;

    return @result;
end;
create function util.Unflatten
(
    @input nvarchar(max)
    ,@delimiter nchar(1)
)
returns table
as
    return
    (
        select
            row_number() over (order by n) - 1 [Idx]
            ,substring(@input, n, charindex(@delimiter, @input + @delimiter, n) - n) [TextValue]
        from util.Numbers
        where n <= len(@input) 
        and substring(@delimiter + @input, n, 1) = @delimiter
    );
go

Add timestamp to photo using ImageMagick

In a Windows batch file:

    rem dptnt.com/2009/04/how-to-add-date-time-stamp-to-jpeg-photos-using-free-software/

    @ECHO OFF
    SETLOCAL
    FOR /R %%G IN (*.jpg) DO CALL :process "%%G"
    GOTO :end

    :process
     SET _inname=%1
     identify -format %%w %_inname% >dttmpfile
     set /p width=<dttmpfile
     Set /a pointsize=%width%/50
    rem  echo ZZ >> dttempfile
     DEL dttmpfile
     ECHO Processing %_inname% ...
     convert %_inname% -gravity SouthEast -font Arial -pointsize %pointsize% -fill orange -annotate +%pointsize%+%pointsize% "%%[exif:DateTimeOriginal]" %_inname%
     EXIT /B
    :end

Type-safe JSON result in ASP.NET MVC

public abstract class BaseController : Controller {
    protected internal JsonResult<T> Json<T>(T data) {
        return Json(data, null /* contentType */, null /* contentEncoding */, JsonRequestBehavior.DenyGet);
    }
    protected internal JsonResult<T> Json<T>(T data, string contentType) {
        return Json(data, contentType, null /* contentEncoding */, JsonRequestBehavior.DenyGet);
    }
    protected internal virtual JsonResult<T> Json<T>(T data, string contentType, Encoding contentEncoding) {
        return Json(data, contentType, contentEncoding, JsonRequestBehavior.DenyGet);
    }
    protected internal JsonResult<T> Json<T>(T data, JsonRequestBehavior behavior) {
        return Json(data, null /* contentType */, null /* contentEncoding */, behavior);
    }
    protected internal JsonResult<T> Json<T>(T data, string contentType, JsonRequestBehavior behavior) {
        return Json(data, contentType, null /* contentEncoding */, behavior);
    }
    protected internal virtual JsonResult<T> Json<T>(T data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior) {
        return new JsonResult<T> {
            Data = data,
            ContentType = contentType,
            ContentEncoding = contentEncoding,
            JsonRequestBehavior = behavior
        };
    }
}

public class JsonResult<T> : JsonResult { }
public class Foo { public int FooId { get; set; } }

// Type-safe result, so you can't accidentally return the wrong type.
[HttpPost]
public JsonResult<Foo> GetSomeFoo() {
    return Json(new Foo { FooId = 1 });
}

Replace alert with SweetAlert

SweetAlert is a nice simple solution for displaying alert messages. Here’s the basic way to replace the built-in alert, so you don’t have to use the custom swal function:

<link href="/styles/sweetalert.css" rel="stylesheet" type="text/css">   
<style type="text/css">
   .sweet-alert h2 { font-size: 21px; font-weight: 500; line-height: 23.1px; }
</style>

<!-- SweetAlert does not work in IE8 or prior -->
<!--[if gt IE 8 | !IE]><!-->
   <script src="/scripts/sweetalert.min.js" type="text/javascript"></script>
   <script type="text/javascript">
       window.alert = function () {
           if (arguments == null) {
               swal(" ");
           } else if (typeof arguments[0] === "number") {
               swal(arguments[0].toString());
           } else {
               swal(arguments[0] || " ");
           }
       };
   </script>
<!--<![endif]-->

Queue and Stack in javascript

Using basic array functions, you can treat an array as a queue (first in first out) or a stack (last in first out);

To act as a queue, use the shift function:

while (arr.length) {
  let val = arr.shift();
  console.log(val);
}

To act as a stack, use the pop function:

while (arr.length) {
  let val = arr.pop();
  console.log(val);
}

Read/write large blob to SQL Server from C#

Rather than try to make it happen in one big command, here’s breaking it out into many commands. Whether or not you use the transaction is up to you and your use case – you could always have a “Completed” column and only set that to true after success, if you wanted to skip a transaction.

First, insert a record, leaving the blob column as an empty byte array, making sure you have access to the primary key of the record you just inserted:

using var conn = new SqlConnection(_config.GetConnectionString("MyDB"));
await conn.OpenAsync().ConfigureAwait(false);
using var tran = (SqlTransaction)await conn.BeginTransactionAsync();
int fileID;
using (var comm = conn.CreateCommand())
{
    comm.Transaction = tran;
    comm.CommandText = @"
        insert dbo.Files (FileName, FileContents)
        values (@FileName, 0x);
        select scope_identity();
    ";
    comm.Parameters.AddWithValue("@FileName", fileName);
    fileID = (int)(await comm.ExecuteScalarAsync().ConfigureAwait(false));
}

Then, in the same connection, write the bytes, 8000 at a time, appending the blob column, and commit the transaction once they’re all done. The “set FileContents.Write” function is a little clumsy, but it works:

using var fileStream = System.IO.File.OpenRead(file);
byte[] buffer = new byte[8000];
int count;
while ((count = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
    byte[] tmp = new byte[count];
    Array.Copy(buffer, 0, tmp, 0, count);
    using var comm = conn.CreateCommand();
    comm.Transaction = tran;
    comm.CommandText = "update dbo.Files set FileContents.write(@ContentChunk, null, null) where FileID = @FileID";
    comm.Parameters.AddWithValue("@FileID", fileID);
    comm.Parameters.AddWithValue("@ContentChunk", tmp);
    await comm.ExecuteNonQueryAsync();
}
await tran.CommitAsync();

To read the data, use the substring function:

private async IAsyncEnumerable<byte[]> ReadFileAsync(int fileID)
{
    int startingByte = 1;
    while (true)
    {
        byte[] bytes;
        using var conn = new SqlConnection(_config.GetConnectionString("MyDB"));
        await conn.OpenAsync().ConfigureAwait(false);
        using var comm = conn.CreateCommand();
        comm.CommandText = @"
            select substring(FileContents, @StartingByte, 8000) [FileContents]
            from dbo.Files
            where FileID = @FileID;
        ";
        comm.Parameters.Add(new SqlParameter("@FileID", SqlDbType.Int) { Value = fileID });
        comm.Parameters.Add(new SqlParameter("@StartingByte", SqlDbType.Int) { Value = startingByte });
        using var rdr = await comm.ExecuteReaderAsync().ConfigureAwait(false);
        if (!await rdr.ReadAsync().ConfigureAwait(false))
        {
            break;
        }
        bytes = (byte[])rdr[0];
        if (bytes == null || bytes.Length == 0)
        {
            break;
        }
        startingByte += bytes.Length;
        yield return bytes;
    }
}


await foreach (var byteArray in ReadImportFileAsync(importBatchID))
{
    fileWriter.Write(byteArray, 0, byteArray.Length);
}

Handlebars in NodeJS

"use strict";

(function() {
    const handlebars = require("handlebars");
    const source = "{{title}}\n"
        + "Hello {{person.name}}, I see that you are {{person.age}} years old.\n"
        + "You have the following cars:\n"
        + "{{#each cars}}\n"
        + "    {{year}} {{make}} {{model}} {{#if color}}(Color={{color}}){{/if}}\n"
        + "{{/each}}\n";

    const template = handlebars.compile(source);
    const data = {
        title: "My Data Object",
        person: { name: "Billy", age: 34 },
        cars: [
            { year: 2015, make: "Ford", model: "Mustang", color: "Red" },
            { year: 2014, make: "Chevy", model: "Corvette" },
            { year: 2013, make: "Dodge", model: "Aries", color: "Yellow" }
        ]
    };
    const result = template(data);
    console.log(result);
})();

/****** OUTPUT *******
My Data Object
Hello Billy, I see that you are 34 years old.
You have the following cars:
    2015 Ford Mustang (Color=Red)
    2014 Chevy Corvette
    2013 Dodge Aries (Color=Yellow)
******* OUTPUT ******/

AJAX in Angular

Regular GET/POST:

$http({
    method: "POST",
    url: "someUrl",
    headers: {
        "Content-Type": "application/json; charset=utf-8"
    },
    data: JSON.stringify({ name: "John Doe" })
}).then(function(response) {
    console.log("Successful response: " + response);
}, function(response) {
    console.log("Error response: " + response);
});


JSONP (in a factory)

// Make sure you include it in DI:  app.factory("myFactory", function ($http, $sce) {
factory.getSomething = function (callback) {

    const URL = "http://something.../?param=someval¶m2=otherval";

    var url = $sce.trustAsResourceUrl(URL);

    $http.jsonp(url, {
        jsonpCallbackParam: "callback"
    }).then(function (response) {
        console.log("Successful response: " + response);
    }, function (response) {
        console.log("Error response: " + response);
    });
};
/*
response:
    data – {string|Object} – The response body transformed with the transform functions.
    status – {number} – HTTP status code of the response.
    headers – {function([headerName])} – Header getter function.
    config – {Object} – The configuration object that was used to generate the request.
    statusText – {string} – HTTP status text of the response.
*/

Render ViewComponent as string

Rendering a View to a string is covered here. Turns out there’s a very similar approach to rendering a ViewComponent as a string. Here’s the code, thanks to this comment on the ASP.NET forums:

    public interface IViewRenderService
    {
        Task<string> RenderToStringAsync(string viewName, object model);
    }

    public class ViewRenderService : IViewRenderService
    {
        private readonly IRazorViewEngine _razorViewEngine;
        private readonly ITempDataProvider _tempDataProvider;
        private readonly IServiceProvider _serviceProvider;

        public ViewRenderService(IRazorViewEngine razorViewEngine,
            ITempDataProvider tempDataProvider,
            IServiceProvider serviceProvider)
        {
            _razorViewEngine = razorViewEngine;
            _tempDataProvider = tempDataProvider;
            _serviceProvider = serviceProvider;
        }

        public async Task<string> RenderToStringAsync(string viewName, object model)
        {
            var httpContext = new DefaultHttpContext { RequestServices = _serviceProvider };
            var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

            using var sw = new StringWriter();
            var viewResult = _razorViewEngine.FindView(actionContext, viewName, false);

            if (viewResult.View == null)
            {
                throw new ArgumentNullException($"{viewName} does not match any available view");
            }

            var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
            {
                Model = model
            };

            var viewContext = new ViewContext(
                actionContext,
                viewResult.View,
                viewDictionary,
                new TempDataDictionary(actionContext.HttpContext, _tempDataProvider),
                sw,
                new HtmlHelperOptions()
            );

            await viewResult.View.RenderAsync(viewContext);
            return sw.ToString();
        }
    }

string result = await _viewRenderService.RenderToStringAsync("Shared/Components/Foo/Default", model);

// Don't forget to register the service so you can use constructor injection in your controller:

public void ConfigureServices(IServiceCollection services)
{
    /// ...
    services.AddScoped<IViewRenderService, ViewRenderService>();
}

Is Development in Razor View

I find myself needing to know if I’m in development from inside a Razor view. In the C# code, you can generally use the #DEBUG preprocessor directive, but it’s not quite so easy in Razor.

I’ve used an extension method on HtmlHelper to kind of cheat, but the “correct” way seems to be to inject the host environment and call the IsDevelopment method:

@using Microsoft.Extensions.Hosting
@inject Microsoft.AspNetCore.Hosting.IWebHostEnvironment HostEnvironment

@if (HostEnvironment.IsDevelopment())
{
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true">
}
else
{
    <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
}

@if (HostEnvironment.IsDevelopment())
{
    <script src="~/js/bundle.js" asp-append-version="true"></script>
}
else
{
    <script src="~/js/bundle.min.js" asp-append-version="true"></script>
}