CSV Mangling in VB.NET

Feb 07
2011

I’ll probably go to hell for this one since I imagine there are much better libraries out there to do the right thing, but I needed to write a quick and dirty function in VB.NET to split some quoted CSV into it’s constituent fields.

This is horrible, but it works for the moment.

    'A function to split a quoted comma delimited string into separate fields
    Public Function GetFields(ByVal row As String) As String()
        Dim fields As New List(Of String)
        If row.Length = 0 Then
            Return fields.ToArray()
        End If
 
        Dim current As Integer = 0
        Dim buffer As New StringBuilder()
        Dim betweenQuotes As Boolean = False
        Dim eol As Boolean = False
        While Not eol
 
            Select Case row(current)
                Case CChar("""")
                    betweenQuotes = Not betweenQuotes
 
                Case CChar(",")
                    If betweenQuotes Then
                        buffer.Append(row(current))
                    Else
                        fields.Add(buffer.ToString())
                        buffer = New StringBuilder()
                    End If
 
                Case Else
                    buffer.Append(row(current))
 
            End Select
 
            current += 1
            eol = (current = row.Length)
        End While
 
        'Add the last field
        fields.Add(buffer.ToString())
 
        Return fields.ToArray()
    End Function

NB, you’ll need to add these lines to the top of the file :

Imports System.Text
Imports System.Collections.Generic

Playing with Powershell

Jan 06
2011

I’ve not actually used powershell before, but we had a requirement to store a list of security camera files and dates in a database so that we could track historical camera activity and this seemed like a good excuse to use it rather than writing a short C# executable.

What I ended up with was this :

# Configuration
$camera_home = "C:\Recordings";
$connection_string = "Data Source=localhost;Initial Catalog=MyDatabase;Trusted_Connection=True";
 
# Sanity Check
if (!(Test-Path $camera_home)) 
{
    [Console]::WriteLine($camera_home + " not found!"); 
    return;
};
 
# Set up the SQL Connection
$conn = new-object System.Data.SqlClient.SqlConnection($connection_string);
$conn.Open();
 
# Get a list of all cameras
$cameras = Get-ChildItem $camera_home;
 
# Iterate over the list
foreach($camera in $cameras)
{
    [Console]::WriteLine($camera);
    $guid = $camera.Name;
 
    # Check whether the current camera exists in the database.
    $camera_getid = new-object System.Data.SqlClient.SqlCommand("select ID from dbo.Camera where CameraGUID = @CameraGUID", $conn);
    $camera_getid.Parameters.Add("@CameraGUID", [System.Data.SqlDbType]"NVarChar").Value = $guid;
    $id = $camera_getid.ExecuteScalar();
    if ($id -eq $Null)
    {
        # Create a new camera record
        $camera_create = new-object System.Data.SqlClient.SqlCommand("insert into dbo.Camera(CameraGUID, CameraName) values(@CameraGUID, 'New Camera')", $conn);
        $camera_create.Parameters.Add("@CameraGUID", [System.Data.SqlDbType]"NVarChar").Value = $guid;
        $camera_create.ExecuteNonQuery();
        $id = $camera_getid.ExecuteScalar();        
    }
 
    # Get the date of the last recording we have a record for
    $camera_getlastrecording = new-object System.Data.SqlClient.SqlCommand("select case when Max(RecordingDate) is null then convert(datetime, '1/1/2001', 103) else MAX(RecordingDate) end from dbo.CameraData where CameraID = @CameraID", $conn);
    $camera_getlastrecording.Parameters.Add("@CameraID", [System.Data.SqlDbType]"Int").Value = $id;
    $lastrecording = $camera_getlastrecording.ExecuteScalar();
    [Console]::WriteLine([String]::Concat("    Last recording date : ", $lastrecording ));
 
    # Get a list of new recordings
    $recordings = Get-ChildItem -recurse -include "*.acsm" $camera_home\$camera | Where-Object {$_.CreationTime -gt $lastrecording};
    if ($recordings -eq $Null) 
    { 
        [Console]::WriteLine([String]::Concat("    No new recordings found."));
        continue 
    }
    [Console]::WriteLine([String]::Concat("    ", $recordings.Count, " new recordings found."));
 
    # Insert new recordings into the database
    foreach($recording in $recordings)
    {
        [Console]::WriteLine([String]::Concat($recording, ",", $recording.CreationTime.ToString("dd/MM/yyyy HH:mm:ss.FF")));
        $recording_create = new-object System.Data.SqlClient.SqlCommand("insert into dbo.CameraData(CameraID, RecordingName, RecordingDate) values(@CameraID, @RecordingName, @RecordingDate)", $conn);
        $recording_create.Parameters.Add("@CameraID", [System.Data.SqlDbType]"Int").Value = $id;
        $recording_create.Parameters.Add("@RecordingName", [System.Data.SqlDbType]"NVarChar").Value = $recording.FullName;
        $recording_create.Parameters.Add("@RecordingDate", [System.Data.SqlDbType]"DateTime").Value = $recording.CreationTime;
        $recording_create.ExecuteNonQuery();
    }
}

Probably the most interesting thing about this post was how long it took to actually make it because of this :

http://wordpress.stackexchange.com/questions/6421/how-can-a-single-line-in-a-blog-post-take-down-my-server/6428#6428

I suspect this kind of thing is going to reoccur if I post anything else with SQL in it, but unfortunately, I don’t have the ability to switch off the ModSecurity rules…

Visit Our Friends!

A few highly recommended friends...

Pages List

General info about this blog...