Saturday, December 31, 2011

wish I knew Jasmine

I want to learn Jasmine. I sat down to start into it just now and I realize I have a long way to go. I want to set up a simple blob of jQuery and try to get it under test. I wrote some markup in which there is a form field followed by a button followed by another form field in a horizontal row. If one clicks, the button, jQuery moves the copy in the first (left) field to the second (right) field. I'd like to get this under test. I'll work towards as much.

 
 


What is Jasmine? It is a Behavior-driven development testing framework for JavaScript. You may download it at http://pivotal.github.com/jasmine/download.html. Generally, when I speak with others, the consensus seems to be that Jasmine is better than JUnit, which is the other player in this space. So far, I know that when one has a .js file that there should be, as a good convention, a –spec.js file of the same name. The spec file will hold the Jasmine test. I've created myscript.js and now the challenge is on me to create myscript–spec.js

More to come?

 
 

myscript.js:

$(document).ready(function() {

   $("#mover").click(function() {

      var leftvalue = $('#lefty').val();

      $('#righty').val(leftvalue)

   });

});

 
 

myscript.js is called by:

<!DOCTYPE html>

<html lang="en">

   <head>

      <script src="jquery-1.5.js" type="text/javascript"></script>

      <script src="myscript.js" type="text/javascript"></script>

   </head>

   <body>

      <input id="lefty" />

      <button type="button" id="mover">Move Right -></button>

      <input id="righty" />

   </body>

</html>

Friday, December 30, 2011

18456 errors

I've had some 18456 errors in attempting to log into MSSQL databases I've created as described here and here. I think I may have sabotaged a login by renaming a database. I don't know what I've screwed up really, but I have figured out how to start over from scratch:

In Microsoft SQL Server Management Studio, create a login under Security, making it sysadmin, then create a database under Databases. When creating the database, set users and specify your login as a user. That is all. Don't worry about creating users at the database itself.

Of Interfaces (3of3)

Please read Of Interfaces (1of3) and Of Interfaces (2of3) before reading this blog posting as it is the last in a series of blog postings. In my last refactoring, I will add a fourth project called InterfaceExample.Database and it too will contain a PersonRepository and reference the core. The UI will reference InterfaceExample.Database instead of InterfaceExample.FileIO (I drop the reference as this project is now depreciated.) and the PersonRepository of InterfaceExample.Database will be wired up in this example to work with the IPersonRepository interface in the core. This switch out should prove fairly painless, thus giving an exposition of how interfaces may be blind to what feeds them.

Addendum 8/16/2015: I am commenting out http://a.yfrog.com/img875/1238/5o5.gif which yfrog has seen fit to replace with some sort of iTunes advertisement. I wish I had not started up my blog hosting images with these clowns.

 
 

What am I trying to do? This change represents a real world decision that one might make to change out the data layer, to replace the element that is driving content with something new. One might look at an app that had simple data populated by flat files and decide that the data really needs to be more sophisticated and hence be driven by an actual database. Such a move would make CRUD functions that are to come in version two of our web site a lot easier to approach. I mentioned that a three-layered approach would have been a bad idea in the prior posting, and I hope you can see now how a separation of concerns, teasing the external dependencies out form the UI and core, allow for this switch to be easy where it would otherwise (in a three-layered approach) be painful. There is really very little to show off in this blog posting compared to my prior two postings, but let's go through it now. I made a database table, gave it some rows, and then wrote two stored procedures for fishing data back out of it with this SQL:

ALTER TABLE dbo.Person ADD CONSTRAINT

   PK_Person PRIMARY KEY CLUSTERED

   (

   Id

   ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,

   ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

GO

ALTER TABLE dbo.Person SET (LOCK_ESCALATION = TABLE)

INSERT INTO Person (Id, Name)

      Values ('58bfe64e-893a-44f0-b8d2-9e6a007bc0fa','Thomas J. Watson Jr.')

INSERT INTO Person (Id, Name)

      Values ('1ba51989-84fb-4a61-8c35-9e6a007bc0fb','T. Vincent Learson')

INSERT INTO Person (Id, Name)

      Values ('850cbe61-4535-4861-bb10-9e6a007bc102','Frank Cary')

INSERT INTO Person (Id, Name)

      Values ('90edbc51-b2b2-4d8d-915b-9e6a007bc0f9','John Opel')

INSERT INTO Person (Id, Name)

      Values ('281872d1-4a1e-4d0c-8dc2-9e6a007bc101','John Akers')

INSERT INTO Person (Id, Name)

      Values ('71c2305a-da77-4dbf-842a-9e6a007bc0fe','Louis V. Gerstner Jr.')

INSERT INTO Person (Id, Name)

      Values ('73a15177-38af-495f-987f-9e6a007bc0fd','Samuel J. Palmisano')

COMMIT

GO

CREATE PROCEDURE GetAllPeople

AS

BEGIN

   SET NOCOUNT ON;

   SELECT * FROM Person

END

GO

CREATE PROCEDURE GetPeopleNotNamedJohn

AS

BEGIN

   SET NOCOUNT ON;

   SELECT * FROM Person WHERE Name Not Like '%John%'

END

GO

 
 

The new PersonRepository:

using System.Collections.Generic;

using System.Data;

using System.Data.SqlClient;

using System.Linq;

using InterfaceExample.Core;

namespace InterfaceExample.Database

{

   public class PersonRepository : IPersonRepository

   {

      public List<Person> GetAllPeople()

      {

         return GetPeopleFromStoredProcedure("GetAllPeople");

      }

      

      public List<Person> GetPeopleNotNamedJohn()

      {

         return GetPeopleFromStoredProcedure("GetPeopleNotNamedJohn");

      }

      

      private static List<Person>

            GetPeopleFromStoredProcedure(string storedProcedureName)

      {

         string key = "Data Source=foo;Initial Catalog=bar;

               Persist Security Info=True;User ID=baz;Password=qux";

         SqlConnection sqlConnection = new SqlConnection(key);

         SqlCommand sqlCommand = new SqlCommand();

         SqlDataReader reader;

         sqlCommand.CommandText = storedProcedureName;

         sqlCommand.CommandType = CommandType.StoredProcedure;

         sqlCommand.Connection = sqlConnection;

         sqlConnection.Open();

         reader = sqlCommand.ExecuteReader();

         DataTable dataTable = new DataTable();

         dataTable.Load(reader);

         sqlConnection.Close();

         List<Person> people = (from DataRow dataRow in dataTable.Rows

               select new Person { Name = dataRow[1].ToString() }).ToList();

         return people;

      }

   }

}

 
 

OK, there are only two existing pieces of code that need to change. One is StructureMap.config:

<StructureMap>

   <PluginFamily Type="InterfaceExample.Core.IPersonRepository"

         Assembly="InterfaceExample.Core" DefaultKey="Default">

      <Plugin Assembly="InterfaceExample.
Database"

            Type="InterfaceExample.
Database.PersonRepository" ConcreteKey="Default" />

   </PluginFamily>

</StructureMap>

 
 

Finally, a using statement in the code behind of our web form changes:

using System;

using InterfaceExample.Core;

using InterfaceExample.
Database;

using StructureMap;

namespace InterfaceExample

{

   public partial class Default : System.Web.UI.Page

   {

      protected void Page_Load(object sender, EventArgs e)

      {

         ObjectFactory.Initialize(x =>

         {

            x.ForRequestedType<IPersonRepository>()

                  .TheDefaultIsConcreteType<PersonRepository>();

         });

         IPersonRepository personRepository =

               ObjectFactory.GetInstance<IPersonRepository>();

         Repeater1.DataSource = personRepository.GetPeopleNotNamedJohn();

         Repeater1.DataBind();

      }

   }

}

Of Interfaces (2of3)

This blog posting piggybacks onto Of Interfaces (1of3) which is another blog posting. Please read it first. This blog posting shows a refactoring to the code detailed in the prior blog posting. I have added a new project called InterfaceExample.FileIO and have moreover added a few files to the two existing projects. We will no longer need the PersonRepository in InterfaceExample.Core so I have just renamed it to be DepreciatedPersonRepository.

Addendum 8/16/2015: I am commenting out http://a.yfrog.com/img877/4972/ukw.gif which yfrog has seen fit to replace with some sort of iTunes advertisement. I wish I had not started up my blog hosting images with these clowns.

 
 

I made a .csv file called IBMCEOs.csv which has this in it:

Thomas J. Watson Jr.,T. Vincent Learson,Frank Cary,John Opel,John Akers,Louis V. Gerstner Jr.,Samuel J. Palmisano

 
 

...and looks like this when one opens it in Excel:

Addendum 8/16/2015: I am commenting out http://a.yfrog.com/img876/804/nki.gif which yfrog has seen fit to replace with some sort of iTunes advertisement. I wish I had not started up my blog hosting images with these clowns.

I'm going to read from this file the list of names solving the problem eluded to in the prior blog posting (a need for abstracting data out of code). For simplicity-sake I am just putting IBMCEOs.csv in the root of the InterfaceExample project, but this is only done to allow the file to live within our web site. It is NOT done to associate IBMCEOs.csv with the web forms project out of a strict need. The .csv file could just as easily be hosted at a different web site or in a folder on a server somewhere having nothing to do with the public-facing content of any web site. I have created the InterfaceExample.FileIO project to manage the procurement of data from the file. This is a wise distinction from the other two projects as FileIO matters are an external dependency which is to say they are neither of the user interface nor the core logic. InterfaceExample.FileIO has a new version of PersonRepository in it that looks like this:

using System.Collections.Generic;

using System.IO;

using System.Linq;

using InterfaceExample.Core;

namespace InterfaceExample.FileIO

{

   public class PersonRepository : IPersonRepository

   {

      public List<Person> GetAllPeople()

      {

         return People();

      }

      

      public List<Person> GetPeopleNotNamedJohn()

      {

         return People().Where(p => !p.Name.Contains("John")).ToList();

      }

      

      private static List<Person> People()

      {

         string path = "C:\\inetpub\\wwwroot\\app\\IBMCEOs.csv";

         TextReader textReader = new StreamReader(path);

         string scrapping = textReader.ReadToEnd();

         textReader.Close();

         string comma = ",";

         string[] contents = scrapping.Split(comma.ToCharArray());

         return contents.Select(name => new Person {Name = name}).ToList();

      }

   }

}

 
 

Great! So what does this have to do with interfaces? Well, I'm getting around to that. Without interfaces we would need to implement a three-layered approach to architecture in which the Core would inherit from the FileIO project (allowing it to create collections of Person objects from data that it got from InterfaceExample.FileIO) and the UI would inherit from the Core (allowing it to get the collections from the Core). This is a bad approach. Why so? I will explain in the next blog posting in this series. Let's think about that later. Trust me when I say it is bad.


 
 

A better approach is to decouple the project that feeds in data from the core logic. Moreover, the FileIO project needs to know about the core logic so that it may create collections of Person which is a class in InterfaceExample.Core. Hence, I have InterfaceExample.FileIO inheriting from InterfaceExample.Core and not the other way around. I have the UI inheriting from both projects as it will also serve as our bootstrapper for an IoC container.


 
 

Alright, instead of having PersonRepository in the core I simply have IPersonRepository in the core in its place. IPersonRepository is an interface. The code behind of our web form in the UI will look to IPersonRepository at the core to populate its repeater. IPersonRepository will then be associated, against the flow of inheritance, with PersonRepository in InterfaceExample.FileIO. The two methods below will thus be wired up to correspond to methods in a different file in a different project.

using System.Collections.Generic;

namespace InterfaceExample.Core

{

   public interface IPersonRepository

   {

      List<Person> GetAllPeople();

      List<Person> GetPeopleNotNamedJohn();

   }

}

 
 

An interface sort of empowers a blind assumption that one may call the methods upon it and that something else will fill-in-the-blanks for what those methods should be. Obviously, as the core does not inherit from the FileIO project, the core is not going to be able to go fishing for the methods itself, so how is the association between IPersonRepository and PersonRepository bound? I am using in IoC (Inversion of Control) container named StructureMap for this. StructureMap.config (in the UI project which is the "bootstrapper" that wires this up) looks like this.

<StructureMap>

   <PluginFamily Type="InterfaceExample.Core.IPersonRepository"

         Assembly="InterfaceExample.Core" DefaultKey="Default">

      <Plugin Assembly="InterfaceExample.FileIO"

            Type="InterfaceExample.FileIO.PersonRepository" ConcreteKey="Default" />

   </PluginFamily>

</StructureMap>

 
 

Finally, our code behind changes somewhat to accommodate calling an interface for a repository instead of a class.

using System;

using InterfaceExample.Core;

using InterfaceExample.FileIO;

using StructureMap;

namespace InterfaceExample

{

   public partial class Default : System.Web.UI.Page

   {

      protected void Page_Load(object sender, EventArgs e)

      {

         ObjectFactory.Initialize(x =>

         {

            x.ForRequestedType<IPersonRepository>()

                  .TheDefaultIsConcreteType<PersonRepository>();

         });

         IPersonRepository personRepository =

               ObjectFactory.GetInstance<IPersonRepository>();

         Repeater1.DataSource = personRepository.GetPeopleNotNamedJohn();

         Repeater1.DataBind();

      }

   }

}

Of Interfaces (1of3)

A friend of mine was asking me about interfaces. I know how they work so I thought I'd throw together an example. There is going to be three blog postings in total. This first one does nothing more than set the stage. (The stuff to do with interfaces will be in the next two postings.) I have built a solution that has two projects: InterfaceExample & InterfaceExample.Core

Addendum 8/16/2015: I am commenting out http://a.yfrog.com/img858/4907/hem.gif which yfrog has seen fit to replace with some sort of iTunes advertisement. I wish I had not started up my blog hosting images with these clowns.

The app is very simply, it just brings up a web page that gives the names of some people. There are all of four files to care about so far. Let's go over them and then that will be it for this first blog posting.

  1. The first one is an object named Person in InterfaceExample.Core:

    namespace InterfaceExample.Core

    {

       public class Person

       {

          public string Name { get; set; }

       }

    }

     
     

  2. Also in InterfaceExample.Core is PersonRepository which exposes two public methods which return collections of the Person object. The collections are crafted right here within this class in lieu of pulling this content in from some external source. There is, thus, no way to update this content outside of the code. If one wants to update this list it has to be done at this file and if this is all of a public-facing web site then one will have to update a deployed .dll upon EVERY update. Such may not be a big deal. A list of the names of U.S. States for example is rarely, rarely going to change. However, let's say, for our example, that this list will need updating and that it is thus a pain point to have it tucked away in code. Well, what are we going to do about that? I'll get to that in the next two postings. We will refactor this code.

    using System.Collections.Generic;

    using System.Linq;

    namespace InterfaceExample.Core

    {

       public class PersonRepository

       {

          public List<Person> GetAllPeople()

          {

             return People();

          }

          

          public List<Person> GetPeopleNotNamedJohn()

          {

             return People().Where(p => !p.Name.Contains("John")).ToList();

          }

          

          private static List<Person> People()

          {

             return new List<Person>()

             {

                new Person() {Name = "Thomas J. Watson Jr."},

                new Person() {Name = "T. Vincent Learson"},

                new Person() {Name = "Frank Cary"},

                new Person() {Name = "John Opel"},

                new Person() {Name = "John Akers"},

                new Person() {Name = "Louis V. Gerstner Jr."},

                new Person() {Name = "Samuel J. Palmisano"}

             };

          }

       }

    }

     
     

  3. InterfaceExample inherits InterfaceExample.Core. While InterfaceExample.Core is a class library, InterfaceExample is a web forms project. I have all of one web form in the project. It looks like this:

    <%@ Page Language="C#" AutoEventWireup="true"

          CodeBehind="Default.aspx.cs" Inherits="InterfaceExample.Default" %>

    <html xmlns="http://www.w3.org/1999/xhtml">

       <head runat="server">

          <title>People</title>

       </head>

       <body>

          <form id="form1" runat="server">

             <h1>People:</h1>

             <asp:Repeater ID="Repeater1" runat="server">

                <ItemTemplate>

                   <br />

                   <%# DataBinder.Eval(Container.DataItem,"Name") %>

                </ItemTemplate>

             </asp:Repeater>   

          </form>

       </body>

    </html>

     
     

  4. Here is the code behind for the web form shown above. It populates the repeater with what comes up from the GetPeopleNotNamedJohn() method at PersonRepository.

    using System;

    using InterfaceExample.Core;

    namespace InterfaceExample

    {

       public partial class Default : System.Web.UI.Page

       {

          protected void Page_Load(object sender, EventArgs e)

          {

             PersonRepository personRepository = new PersonRepository();

             Repeater1.DataSource = personRepository.GetPeopleNotNamedJohn();

             Repeater1.DataBind();

          }

       }

    }

Thursday, December 29, 2011

Someone want to explain functional programming to me?

Today I watched this presentation by Runar Bjarnason on Functional Programming and attempted to make an example in code that showed off both a High Order Function and Recursion. I'm pretty sure I've screwed it up. I'm going to have to ask some of the guys at work what I did wrong on Tuesday when AMD is back from break, but in the meantime, here is my code. It is an expansion of the example I started here. I paint the screen with five German numbers in a view like so:

@model List<string>

<h1>Even German Numbers Of Single Digit Length:</h1>

@foreach(string item in Model)

{

   <p>@item</p>

}

 
 

This drives my view. Here I am trying to do some looping. I know this has to be the wrong way to go about it and the wrong way to maintain the numeric state. Nuts. It has been suggested to me (I have notes here) that a Func may be passed about and progressively change shape as it moves based on the things that touch it. I'm not sure how to represent this.

using System;

using System.Collections.Generic;

using System.Web.Mvc;

using Core;

namespace FrontEnd.Controllers

{

   public class HomeController : Controller

   {

      public ActionResult Index()

      {

         List<string> foo = new List<string>();

         Func<KeyValuePair<Int16, Int16>, KeyValuePair<Int16, string>> bar =

               DeutschDigitStateMachine.ChangeShape;

         KeyValuePair<Int16,string> baz = bar(new KeyValuePair<Int16, Int16>(0,0));

         while (baz.Key < 10)

         {

            if (baz.Key < 10) foo.Add(baz.Value);

            baz = bar(new KeyValuePair<Int16, Int16>(baz.Key, 2));

         }

         return View(foo);

      }

   }

}

 
 

Here is my High Order Function. TryToGiveGermanNameForSingleDigit is what it was in the previous code.

using System;

using System.Collections.Generic;

namespace Core

{

   public static class DeutschDigitStateMachine

   {

      public static KeyValuePair<Int16,string> ChangeShape(KeyValuePair<Int16,Int16>

            halvesOfDigit)

      {

         Int16 digit = Convert.ToInt16(halvesOfDigit.Key + halvesOfDigit.Value);

         Func<Int16, string> convertInteger =

               DigitToDeutschTranslator.TryToGiveGermanNameForSingleDigit;

         return new KeyValuePair<Int16, string>(digit,convertInteger(digit));

      }

   }

}

 
 

I end up with the following HTML which means that it works. And yet, I feel I've screwed up the implementation. Any thoughts anyone?

<h1>Even German Numbers Of Single Digit Length:</h1>

<p>null</p>

<p>zwei</p>

<p>vier</p>

<p>sechs</p>

<p>acht</p>

Why can't I see a v3.5 setting at the Application Pool in IIS?

The ASP.NET 3.5 Framework is the ASP.NET 2.0 Framework with some new compiler tricks. Therefore a 3.5 web site is going to use the v2.0 setting at the Application Pool configurations in IIS. The 4.0 Framework is a standalone version and uses the v4.0 setting at the Application Pool configurations.

Wednesday, December 28, 2011

ease the default Windows Server 2008 R2 security

In Windows Server 2008 R2, click on the icon for Server Manager at the immediate left of the Start button. This will bring up the Server Manager pane. Click on Configure IE ESC to get rid of a lot of the overbearing default security. This will allow you to download via IE.

Press ALT when in Windows Explorer is open to expose the Tools menu.

It can be hidden in Windows Server 2008 R2, not allowing one to go to Tools > Folder Options to unhide file extensions and hidden files as suggested here.

Tuesday, December 27, 2011

empower IIS at your Rackspace server

I could not see IIS at my Rackspace server. It turned out that the management tools just were not installed. I called a tech and he told me to click on the icon for Server Manager at the immediate left of the Start button. I did so and then, at the dialog that appeared, I went to Server Manager (Jaeschke) > Roles > Web Server (IIS) > Add Role Services and from here I was/am able to install various things such as the typical IIS GUI interface and FTP capabilities. Yay!

Monday, December 26, 2011

sysadmin

I got this error when I attempted to view the tables of a database in MSSQL Server Management Studio Express 2008:

The SELECT permission was denied on the object 'extended_properties', database 'mssqlsystemresource', schema 'sys'. (Microsoft SQL Server, Error: 229)

 
 

The way out: At the server, I double-clicked on my login at Security > Logins and then went to Server Roles where I added sysadmin

exposing SQL Server databases to the outside world

I just had a Rackspace tech talk me through how to prep SQL Server to allow for a database I had created in Microsoft SQL Server 2008 R2 to be seen from Microsoft SQL Server Management Studio Express 2008 outside of the server it lives on:

  • From the start menu, go to: Microsoft SQL Server 2008 R2 > Configuration Tools > SQL Server Configuration Manager and then click on SQL Server Services under SQL Server Configuration Manager (Local) and from there make sure SQL Server Browser is running. If it is not, make it run. If the start option is disabled: Right-click on SQL Server Browser, then go to Properties, then go to the Service tab, and finally set Start Mode to Automatic. This will make it so SQL Server Browser may be run.
  • The tech had me go to Client Protocols under SQL Native Client 10.0 Configuration (32bit) under SQL Server Configuration Manager (Local) to be user TCP/IP was enabled.
  • The tech had me type wf.msc at the command line to launch Windows Firewall with Advanced Security. I right clicked at Inbound Rules under Windows Firewall with Advanced Security on Local Computer to create a new rule and ended up creating a rule for port 1433.
  • We checked on something else too, but now I can't remember what it was.

I'm reading up on Scott Hanselman's notes on MVC4

I'm reading up on Scott Hanselman's notes on MVC4 here. The highlights:
 

  • Get it here!
     
  • Get the opera mobile emulator here.
     
  • He touches on CSS media queries:

    @media only screen and (max-width: 850px) {
     
  • And the viewport HTML5 tag which is new to me:

    <meta name="viewport" content="width=device-width">

    A mobile browser will scale to fit everything in the viewport tag onto the screen without regard to how big it is.
     
  • And now the magic: If you have view labeled whatever.cshtml, you need only create whatever.Mobile.cshtml in the same folder to override the default view in a mobile setting!

Sunday, December 25, 2011

more Joel stuff

PHP calls them associative arrays. .NET call them HashTables. Ruby calls them hashes. In JavaScript they are just objects.

Call Dispatch: calling a method and the routing that goes to the object to fish for the method - in a dynamic setting one was create failover for methods that are not strictly at the object and bypass the compiler for just-in-time mechanics

at Joel's right now for Christmas

Things Joel mentioned:
  • Inherit from DynamicObject to make a dynamic object.
  • Use the operator keyword to override what operators do.

Saturday, December 24, 2011

function () versus $(document).ready in jQuery

<div id="immediately">Hello</div>

<div id="whendoneloading">World</div>

<script type="text/javascript">

   (function () {

      $('#immediately').attr('style', "display:none;");

      $(document).ready(function () {

         $('#whendoneloading').attr('style', "display:none;");

      });

   })();

</script>

 
 

In the blob of markup above this will run right away...

$('#immediately').attr('style', "display:none;");

 
 

...while this will run when the page finishes loading...

$('#whendoneloading').attr('style', "display:none;");

When making a horizontal movie with an iPhone you will want to keep the button at the right.

Otherwise the movie will be upside down when you drag it into a Windows environment.

Entities have both state and lifecycle

I'm looking at some of my old tweets from No Fluff Just Stuff earlier this year that have to do with Eric Evans' Domain Driven Design. They include:
  • . @thepaulrayner good talk on DDD! #nfjs http://twitpic.com/5u6rul
  • #nfjs DDD: don't update a date at "Terms & Conditions," create a new "Terms & Conditions" http://twitpic.com/5u6haq
  • #nfjs DDD: a value object is immutable - example: abstract to a "Terms & Conditions" value object appropriate bits of a "Warranty" entity
  • #nfjs DDD: Entities have both state and lifecycle - example: a warranty has an enum for status with options: {Pending, Active, Expired}
  • #nfjs DDD: types of objects are Data Transfer Objects (just getters and setters), Entities, and Value Objects
  • http://twitpic.com/5u61q2 of DDD: question to ask business owner when trying to figure this out: What do you do when you adjudicate? #nfjs
The fourth bullet contains "Entities have both state and lifecycle" and we are getting into a building an object of this nature, which Eric Evans would consider a true entity, in our project. The object has states and there are different actions which take one from a state to a state. There is both a happy path forward and some exceptions for routing one backwards too.

about:cache

Going to about:cache in Firefox is a good way to get at the HTML being transmitted by a web site if you are struggling with a web site that is trying to block this content. (Ctrl-U normally displays the HTML source in Firefox. When this doesn't work, it's time to get mad!)

Click on "List Cache Entries" to go to about:cache?device=disk to see a list of cached stuff. Hey, there is a lot of noise here, huh? You can trim it down by clearing your cache and then immediately going to the page you wish to scrape and then immediately back to "List Cache Entries." Clear your cache in Firefox this way:

Tools > Options > Network > Clear Now

 
 

At any one line item at "List Cache Entries" one may click through to a page summary which will often expose a path to the cache like so:

C:\Users\whatever\AppData\Local\Mozilla\Firefox\Profiles\whatever\Cache

 
 

That said, an HTML scrape of the page should just run along the right side of the details. I use headspring.com in the image below as an example, however it was yfrog.com that inspired me to find a way around being blocked when I attempt to view HTML source.

Addendum 8/20/2015: I am commenting out http://a.yfrog.com/img857/6117/bg96.gif which yfrog has seen fit to replace with some sort of iTunes advertisement. I wish I had not started up my blog hosting images with these clowns.

Addendum 3/25/2014: Tools > Options > Network > Clear Now ...above should have "Advanced" between the "Options" and "Network." Maybe Firefox was different when I wrote this blog posting years ago. Maybe, alternatively, I just made a mistake.

Friday, December 23, 2011

The hard-to-see, camouflaged seam between IQueryable and IEnumerable and what it means for LinqSpecs

This line of code worked great:

foreach (Division division in DivisionRepository.FindAll(DivisionSecurityFilteringHelper.SpecificationForAllSecurityPermissionedDivisions(ListView.UserContext))) foreach (Account account in division.Accounts) OrderFilter.Accounts.Add(account.Id, account.Name);

 
 

Resharper suggested I refactor it to this however:

foreach (Account account in DivisionRepository.FindAll(DivisionSecurityFilteringHelper.SpecificationForAllSecurityPermissionedDivisions(ListView.UserContext)).SelectMany(division => division.Accounts)) OrderFilter.Accounts.Add(account.Id, account.Name);

 
 

Then it didn't work so well, returning:

Could not parse expression 'value(NHibernate.Linq.NhQueryable`1[AMD.Avalanche.Core.Entities.Division]).Where(d => (d.OwnersGroup.Profiles.Where(p => (p.Id == f740904e-3e43-4644-8194-9f8700fb904b)).Any() OrElse Invoke(d => d.OwnersGroup.Groups.Any(g => g.Profiles.Any(p => (p.Id == f740904e-3e43-4644-8194-9f8700fb904b))), d))).SelectMany(division => division.Accounts)': This overload of the method 'System.Linq.Queryable.SelectMany' is currently not supported, but you can register your own parser if needed.

 
 

When an IQueryable is executed it will pop-off (forgive the email term, it is marginally inappropriate) its contents to an IEnumerable or at least try to. In the second line of code above, I am shoving the concerns of a child object onto the IQueryable and thus sabotaging its ability to be popped-off. I don't have to shove these concerns onto the IQueryable, and yet there might be a little bit of optimization if I did do so, so it was worth a try. LinqSpecs are tricky.

XCode/Cocoa/jQuery Mobile and other random things I heard yesterday from Joel

I keep blogging of random things I hear...

XCode is the IDE for Cocoa for developing iPhone apps and other Mac OS X stuff. Also there is a jQuery Mobile Framework to use with mobile stuff. Get XCode at the AppStore.

Thursday, December 22, 2011

Active Directory SIDs

S-1-5-21-249263827-1212357926-315576832-512092 is an example of an Active Directory SID. The unique ids for Active Directory profiles are not GUIDs, they have a different shape. This touches on it some.

language-specific resource files

ASP.NET with read the "culture" off of the executing thread (based on your browser). Naming a resource (.resx) with the appropriate name will allow ASP.NET to make a match on a culture without any wire-up.

Tuesday, December 20, 2011

Sunday, December 18, 2011

the current way we aggregate LinqSpecs

This shows how Rafael is aggregating LinqSpec specifications:

using System.Collections.Generic;

using System.Linq;

using OurApp.Core.Entities;

using OurApp.Core.Specs;

using OurApp.Core.Utils;

using OurApp.Core.Utils.LinqSpecifications;

namespace OurApp.Web.UI.LinqSpecifications

{

   public abstract class FilterModelBasedSpecificationBuilderBase<T> :

         IFilterModelBasedSpecificationBuilder<T> where T : BaseEntity

   {

      public IList<IFilterModelBasedSpecificationRule<T>>

            FilterModelBasedSpecificationRules { get; set; }

      public SpecificationBuilder<T> Build(SpecificationBuilder<T> specificationBuilder,

            IFilterModel filterModel)

      {

         FilterModelBasedSpecificationRules

               .Where(rule => rule.ShouldApply(filterModel))

               .ForEach(rule => rule.Apply(filterModel, specificationBuilder));

         if (specificationBuilder.ToSpecification() == null)

               specificationBuilder.AddOr(BaseSpecs<T>.Noop());

         return specificationBuilder;

      }

   }

}

 
 

The class above will be a parent in inheirtance for an object-level concern.

using OurApp.Core.Entities;

namespace OurApp.Web.UI.LinqSpecifications.OrderSpecifications

{

   public class OrderFilterModelBasedSpecificationBuilder :

      FilterModelBasedSpecificationBuilderBase<Order>

   {

   }

}

 
 

The Spring.NET wireup:

<object id="orderSpecificationAggregator"

      type="OurApp.Core.Utils.LinqSpecifications.Aggregators

      .OrderSpecificationAggregator,OurApp.Core" singleton="false">

   <property name="FilterModelBasedSpecificationBuilder"

         ref="orderFilterModelBasedSpecificationBuilder" />

</object>

<object id="orderFilterModelBasedSpecificationBuilder"

      type="OurApp.Web.UI.LinqSpecifications.OrderSpecifications

      .OrderFilterModelBasedSpecificationBuilder,OurApp.Web.UI" singleton="false">

   <property name="FilterModelBasedSpecificationRules">

      <list element-type="OurApp.Core.Utils.LinqSpecifications

            .IFilterModelBasedSpecificationRule<OurApp.Core.Entities.Order>

            ,OurApp.Core">

         <object type="OurApp.Web.UI.LinqSpecifications.OrderSpecifications.

               ApprovedStatusSpecificationRule,OurApp.Web.UI" />

         <object type="OurApp.Web.UI.LinqSpecifications.OrderSpecifications.

               StatusSpecificationRule,OurApp.Web.UI" />

         <object type="OurApp.Web.UI.LinqSpecifications.OrderSpecifications.

               PendingMeSpecificationRule,OurApp.Web.UI" />

         <object type="OurApp.Web.UI.LinqSpecifications.OrderSpecifications.

               PendingMeCostCenterSpecificationRule,OurApp.Web.UI" />

         <object type="OurApp.Web.UI.LinqSpecifications.OrderSpecifications.

               PendingMeAccountSpecificationRule,OurApp.Web.UI" />

         <object type="OurApp.Web.UI.LinqSpecifications.OrderSpecifications.

               RequesterSpecificationRule,OurApp.Web.UI" />

      </list>

   </property>

</object>

 
 

The sanity checking for one of the concerns:

using OurApp.Core.Entities;

using OurApp.Core.Specs;

using OurApp.Core.Utils;

using OurApp.Core.Utils.LinqSpecifications;

using OurApp.Web.UI.Models;

using OurApp.Web.UI.Util;

namespace OurApp.Web.UI.LinqSpecifications.OrderSpecifications

{

   public class ApprovedStatusSpecificationRule :

         IFilterModelBasedSpecificationRule<Order>

   {

      public bool ShouldApply(IFilterModel filterModel)

      {

         var orderFilterModel = (OrderFilterModel)filterModel;

         return orderFilterModel.Status == OrderStatusFilterState.PendingDelivery.ToString();

      }

      public SpecificationBuilder<Order> Apply(IFilterModel filterModel,

            SpecificationBuilder<Order> specificationBuilder)

      {

         specificationBuilder.AddAnd(OrderSpecs.ApprovedStatusCriteria());

         return specificationBuilder;

      }

   }

}

 
 

One of the concerns:

using System.Linq;

using OurApp.Core.Entities;

using OurApp.Core.Infrastructure;

using LinqSpecs;

namespace OurApp.Core.Specs

{

   public class OrderSpecs:BaseSpecs<Order>

   {

      public static Specification<Order> ApprovedStatusCriteria()

      {

         return new AdHocSpecification<Order>(o => o.Status_private

               == (int)OrderStatusCode.Approved);

      }

cast a property from a collection to another collection

string[] names = ProfileRepository.GetAll().Select(p => p.Name).ToArray();

Saturday, December 17, 2011

Checking a checkbox by pressing the spacebar WILL fire the .click jQuery event.

I tested in Firefox, IE, and Chrome. There is thus little reason to put .focus event logic around a checkbox to try to catch the keyboard version of clicking. In fact, I've had .focus logic get in the way.

Friday, December 16, 2011

two things

  • Heroku (pronounced her-OH-koo) is a cloud application platform – a new way of building and deploying web apps. The service lets app developers spend more of their time on their application code, not managing servers, deployment, ongoing operations, or scaling.
  • YAML is for data serialization.

Thursday, December 15, 2011

Navicat

Navicat is a tool like MSSQL Management Studio Express, only it doesn't just interface with MSSQL. It interfaces with numerous varieties of databases.

Amplify

My bank, Amplify, sent me an email this morning suggesting that I download a mobile app. I was fascinated by where three offered links led:

Wednesday, December 14, 2011

XHR

Wikipedia is so wise: XMLHttpRequest (XHR) is an API available in web browser scripting languages such as JavaScript. It is used to send HTTP or HTTPS requests directly to a web server and load the server response data directly back into the script. The data might be received from the server as XML text or as plain text. Data from the response can be used directly to alter the DOM of the currently active document in the browser window without loading a new web page document.

returnParameter.Value.ToString().PadLeft(10, '0');

Craig suggested that this is the better way to facilitate what I was chasing here.

Tuesday, December 13, 2011

string manipulation cheatsheat

http://idunno.org/archive/2004/07/14/122.aspx seems like a cool cheatsheet on string formatting! I like:

String.Format("--{0,10}--", "test");

 
 

Which spits out:

--      test--

 
 

I made an order number at least six digits like so:

string foo = String.Format("{0,10}", row["OrderNumber"].ToString()).Replace(" ","0");

 
 

As we are discussing string manipulations, please see:

put spaces before capital letters in a string

From here I stole somewhat to come up with:

using System.Text.RegularExpressions;

namespace OurApp.Core.Utils

{

   public static class StringSpaceMaker

   {

      public static string AppendSpacesBeforeCapitalLetters(string value)

      {

         value = Regex.Replace(value, "[A-Z]", " $0");

         return value.Substring(1, value.Length - 1);

      }

   }

}

 
 

I got it under test like so:

using OurApp.Core.Utils;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace OurApp.Tests.Unit.Core.Utils

{

   [TestClass]

   public class StringSpaceMakerTest

   {

      [TestMethod]

      public void MayAppendSpacesBeforeCapitalLetters()

      {

         string value = "IThinkThereforeIAm";

         value = StringSpaceMaker.AppendSpacesBeforeCapitalLetters(value);

         Assert.AreEqual("I Think Therefore I Am", value);

      }

   }

}

 
 

Why do I need this? I'm going to use this to cast enum values where words AreJammedTogether to readable text painlessly.

use .ElementAt to get an item in an IEnumerable by index

var foo = ListView.ObjectList.ElementAt(counter);

I stole this from here.

Monday, December 12, 2011

cast an NHibernate proxy to a different-than-default type

Let's say Foo is a more specific version of Bar. Let's say that the table for Bar has two columns...

  1. Id
  2. Name

 
 

...and that the table for Foo has two columns...

  1. Id
  2. SomethingMore

 
 

...and that every Id in Foo has a corresponding Id in the Bar table, (although not necessarily the other way around as Baz might also be a child variation of Bar).

 
 

Would there be a way to cast the NHibernate proxy for a Bar to a Foo if the Bar was a Foo? Yes!

var proxy = myObject.ChildrenOfMyObject.First().Bar;

Foo foo = null;

if (proxy is INHibernateProxy)

{

   var lazyInitializer = ((INHibernateProxy)proxy).HibernateLazyInitializer;

   foo = lazyInitializer.GetImplementation() as Foo;

}

var whatever = foo.SomethingMore;

Alt-Shift-Enter takes one to "full screen" mode in Visual Studio

cool trick

Sunday, December 11, 2011

at AgileAustin this past Tuesday

Janelle Klein of New Iron, the Program Chair of AgileAustin, hosted a meeting that was an open space on: How do we go from principals/practices/enthusiasm to REAL honest-to-goodness improvement? For example, Janelle offered:

  • For everything you really want to improve, make a story for it and put it into your upcoming sprint. Make it an action item. Beware the constant pressure to just live in the now (and "get stuff done") and not improve.

 
 

The meeting was on December 6. I am just now getting around to making my notes presentable as I have been sick. I attended a group discussion that had to do with how to have code reviews that "you can live with" given that most employers do not want to budget for pair programming. My notes:

  • Why do teams want to do code reviews? Answer: Programmers care about maintainability.
  • FishEye and Crucible are code review tools not unlike SmartBear (which I used at framesdirect.com). Crucible works in tandem with FishEye and is used for collocated teams.
  • If a defect makes it through a review, perhaps the reviewer should have to fix the defect. This was a suggestion.
  • A point of discussion: Should a code review be communal or between two individuals (the reviewer and the reviewed)? If you send a swath of code to the whole team for review, no one owns it and, likely, no one is going to comment on it. Yet, a goal of a review may be to educate the team as to how the code works. Perhaps communal ownership should not be measured in finding defects. These insights suggested a division between reviewing code for knowledge sharing and reviewing code for bug hunting and maintainability with regards to who should be involved.
  • VNC (Virtual Network Computing) screen sharing reduces the cost of reviews in many cases, taking reviews from formally scheduled events to the realm of "Hey dude, got a second?"
  • It is wise to have defect retrospectives.
  • There was discussion over a concern that a code review process which is too formal leads participants to zone out and participate less. The need for structure was nonetheless emphasized. The end consensus seemed to be that a team should start with a rigorous process and then perhaps scale back to a lightweight process. (The team should build up instincts for what works.)
  • Should a code review be subjective or objective? There seemed to be a desire for both. Hard limits for code review such as code formatting requirements seem prudent, yet other concerns (example: architectural approaches) are indeed more subjective. Zen and the Art of Motorcycle Maintenance was referenced underscoring that objective is not superior to subjective.
  • Does a junior/junior code review work to some or any extent as a junior/senior code review might? Such reviews could allow developers to grow together or could allow developers to reinforce each other's bad work. There was not a consensus.
  • Michael Fagan invented an inspection process for defects. The reference point for a defect is a shared standard. This develops a community approach and takes the personal sting out of criticism.
  • One participant was "not too worried about design" (in terms of reviews) given how community-owned it is. Teams whiteboard design all the time.
  • Of checklists:
    • NASA used to use checklists. Once they found an escape they would add it to their checklists. When the trouble no longer appeared in checking it came off the checklist(s).
    • Community has to own a checklist and keeping a checklist community owned can be a challenge. Different checklists to come in from different angles (design, etc.) is a good solution here.
    • A record of commonly occurring bugs may be addressed and documented by way of a checklist.
    • Things that might appear on checklists:
      • Review of Dependencies!
      • Are there any one-off loop errors?
      • Look for inappropriate mutuable state and inappropriate public setters.
      • Every time I do one of these I have to remember to do this other thing over here.

 
 

Interesting things said that were slightly off topic:

  • Architecture is a process of restraints!
  • It was argued that tests that straddle a lot of concerns may be, in fact, very effective. It was also argued that obscure tests are bad because the day the architecture changes, the tests are hard to understand and that tests should be clear when they fail as to why they are failing.

Friday, December 9, 2011

make a multi-select dropdown based on an enum

<select id="Status" name="OrderFilter.Statuses" multiple="multiple">

   @foreach (var enumValue in Enum.GetValues(typeof(OrderStatusCode)))

   {

      var hint = ((int) enumValue);

      var name = ((OrderStatusCode)enumValue);

      <option value="@hint"

         @if(statuses.Contains(hint)) {

            @:selected

         }

      >@name</option>

   }

</select>

 
 

In this example statuses would be something predefined earlier in the Razor markup. For simplicity sake, one could think of it like so:

@{ int[] statuses = new int[]{3,7}; }

 
 

Note the use of @: which is called the pig operator.

 
 

What follows the pig operator will behave as if wrapped in <text></text>

.First() works with both IEnumerable and List generics in C#

var foo = order.OrderItems.First().Quantity;

 
 

This has extensive detail on the subject.

Tuesday, December 6, 2011

get an enum's vanity value from its int value

Volume myVolume = (Volume)volInt;

 
 

I stole this from here.

System.ArgumentException: Cannot change DataType of a column once it has data.

I got the error above when I tried to cast a DataColumn full of int values to DataColumn of a string type like so:

int statusIndex = myDataTable.Columns.IndexOf("Status");

myDataTable.Columns[statusIndex].DataType = typeof(string);

   

I had to solve the problem the hard way:

myDataTable.Columns.Add("StatusString", typeof(string));

myDataTable.Rows.ForEach(row =>

{

   row["StatusString"] = row["Status"].ToString();

});

myDataTable.Columns.Remove("Status");

int statusIndex = myDataTable.Columns.IndexOf("StatusString");

myDataTable.Columns[statusIndex].ColumnName = "Status";

rename a column at a DataTable

dt.Columns[2].ColumnName = "Column3";

Monday, December 5, 2011

hgroup

<hgroup> is an HTML5 tag. It surrounds other H tags like so:

<hgroup>

<h1>Welcome to my WWF</h1>

<h2>For a living planet</h2>

</hgroup>

add a column at the end of a DataTable and then move it to be the leftmost/first column in the DataTable

public DataTable FixupDataTable(DataTable myDataTable)

{

   myDataTable.Columns.Add("Order Number", typeof(string));

   myDataTable.Rows.ForEach(row =>

   {

      row["Order Number"] = string.Format(

            "<!--{1}--><a href='/Order/Details?id={0}'>{1}</a>", row["Id"], row["OrderNumber"]);

   });

   myDataTable.Columns.Remove("OrderNumber");

   myDataTable.Columns[myDataTable.Columns.Count - 1].SetOrdinal(0);

   return myDataTable;

}

XPath and XSLT

If you don't want to latch onto a control with JavaScript/jQuery by way of an id, the alternative is to use the XPath which is a means for querying doms in XSLT, a language that transforms XML into reshapen XML or HTML. The process of "I want the third text box in the second div in the body" that one associates with recorded Selenium scripts is an example of this, I think.

.js caching

We had a conversation today about the pain of .js files being cached and what to do about it. One thing that could be done would be to have a random number bubble up from C# into a Razor view to follow a call to a .js file like so:

whatever.js?@ViewBag.MyRandomNumber

...but of course, the problem with this is that the .js file is never cached which leads to another set of pain points. Perhaps it's better to use the current date, specific only to the day. We could start versioning our .js files but that could get painful too.

Chirpy minify

You may ask Chirpy to watch for changes to (or the creations of) JavaScript files ending in a certain pattern. We use yourfilenamehere.full.js as our Chripy-friendly convention. Chirpy will minify the watched files, making code-condensed, less-readable versions of the .full.js files. We used the minify versions in our app for performance and keep the unminified versions as grounds for doing work in .js files that is easily readable. Do not edit a minified file. The change will be overwritten when the fatter parent file gets updated, demanding the creation of a new minified script.

Sunday, December 4, 2011

HtmlGenericControl

Today I helped a friend with a web forms project and learned that one may cast a div with a runat=server tag to a HtmlGenericControl at a code behind. Here are some related links:

ten must have C# string manipulations

Well, actually here are nine string manipulations you cannot live without and one you will never need. These tests passed for me:
  1. Determine if a string contains another string:

    [TestMethod]

    public void ShouldFindLiarInBilliards()

    {

       string billiards = "billiards";

       string liar = "liar";

       int matchNotation = billiards.IndexOf(liar);

       bool isMatch;

       if (matchNotation != -1)

       {

          isMatch = true;

       } else {

          isMatch = false;

       }

       Assert.AreEqual(true,isMatch);

    }


     

     
  2. Split a string into an array of strings based upon a particular character:

    [TestMethod]

    public void BilliardsShouldSplitIntoThreePieces()

    {

       string billiards = "billiards";

       string splitChar = "i";

       string[] splitPieces = billiards.Split(splitChar.ToCharArray());

       Assert.AreEqual(3, splitPieces.Length);

       Assert.AreEqual("b", splitPieces[0]);

       Assert.AreEqual("ll", splitPieces[1]);

       Assert.AreEqual("ards", splitPieces[2]);

    }


     

     
  3. Drop the last character on a string:

    [TestMethod]

    public void MayMakeBilliardsSingular()

    {

       string billiards = "billiards";

       string billiard = billiards.TrimEnd('s');

       Assert.AreEqual("billiard",billiard);

    }


     

     
  4. Trim the last few characters and/or the first few characters off of a string:

    [TestMethod]

    public void MayTrimBilliardsToLiarWithSubstring()

    {

       string billiards = "billiards";

       billiards = billiards.Substring(0, 7);

       Assert.AreEqual("billiar",billiards);

       billiards = billiards.Substring(3, 4);

       Assert.AreEqual("liar",billiards);

    }


     

     
  5. Use regular expressions for determining if a string is of a particular shape:

    [TestMethod]

    public void BilliardsIsNotAnEmailAddress()

    {

       string billiards = "billiards";

       bool isMatch;

       if (Regex.IsMatch(billiards, @"^\w+([-+.']\w+)*@\w+([-+.']\w+)*\.\w+([-+.']\w+)*$"))

       {

          isMatch = true;

       } else {

          isMatch = false;

       }

       Assert.AreEqual(false, isMatch);

    }


     

     
  6. Convert a string to title case:

    [TestMethod]

    public void MayCastSentenceToTitleCase()

    {

       string billiards = "Come to Tom's billiards room!";

       CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;

       TextInfo textInfo = cultureInfo.TextInfo;

       billiards = textInfo.ToTitleCase(billiards);

       Assert.AreEqual("Come To Tom's Billiards Room!", billiards);

    }


     

     
  7. Replace a piece of a string with other characters:

    [TestMethod]

    public void MayReplaceLiarWithTruthTeller()

    {

       string billiards = "billiards";

       billiards = billiards.Replace("liar", "truth-teller");

       Assert.AreEqual("biltruth-tellerds", billiards);

    }


     

     
  8. Encrypt a string:

    [TestMethod]

    public void MayEncryptBilliards()

    {

       string billiards = "billiards";

       System.Security.Cryptography.MD5CryptoServiceProvider objCript;

       objCript = new System.Security.Cryptography.MD5CryptoServiceProvider();

       byte[] bytes = System.Text.Encoding.UTF8.GetBytes(billiards);

       bytes = objCript.ComputeHash(bytes);

       System.Text.StringBuilder builder = new System.Text.StringBuilder();

       foreach (byte bit in bytes)

       {

          builder.Append(bit.ToString("x2").ToLower());

       }

       billiards = builder.ToString();

       Assert.AreEqual("dcffcb328215e331284aacb75781da68", billiards);

    }


     

     
  9. Cast a double and/or a decimal to a string while formatting it as currency:

    [TestMethod]

    public void MayFormatBilliardsHallDailyRevenueAsCurrency()

    {

       decimal decimalValue = 1921.39m;

       string decimalString = String.Format("Day: {0:C}", decimalValue);

       Assert.AreEqual("Day: $1,921.39", decimalString);

       double doubleValue = 1921.39;

       string doubleString = String.Format("Day: {0:C}", doubleValue);

       Assert.AreEqual("Day: $1,921.39", doubleString);

       Assert.AreEqual(decimalString,doubleString);

    }


     

     
  10. Reverse a string (which you will never need to do):

    [TestMethod]

    public void MayReverseBilliards()

    {

       string billiards = "billiards";

       char[] characterArray = billiards.ToCharArray();

       Array.Reverse(characterArray);

       billiards = new string(characterArray);

       Assert.AreEqual("sdraillib",billiards);

    }


     

     
For more information on string manipulations, please click the image here:

Saturday, December 3, 2011

there's always something to do to keep you from what you really should be doing

Over a quarter century ago I read, as a child, the children's book The Phantom Tollbooth. My favorite character: Terrible Trivium, a faceless demon of professional guise who tortures his victims with repetitive inane chores which are both mundane and Sisyphean.


As an adult I've come to realize that this demon really exists! It's not just some nonsense in a kid's book!

If you spend all day doing patchwork to maintain bad code patterns, maybe it's time to see the forest and not the trees. It's probably time to think of a solution or get out.

a Terrible Trivium quote: "If you only do the easy and useless jobs, you'll never have to worry about the important ones which are so difficult. You just won't have the time. For there's always something to do to keep you from what you really should be doing..."

Friday, December 2, 2011

get the row count of all tables

SELECT '[' + SCHEMA_NAME(t.schema_id) + '].[' + t.name + ']' AS fulltable_name,

SCHEMA_NAME(t.schema_id) AS schema_name, t.name AS table_name,

i.rows

FROM sys.tables AS t INNER JOIN

sys.sysindexes AS i ON t.object_id = i.id AND i.indid < 2

Thursday, December 1, 2011

prevent a form from submitting with jQuery

(function () {

   $('form').submit(function (e) {

      var atLeastOneException = false;

      if ($('#myField').val() == '') {

         atLeastOneException = true;

      }

      if (atLeastOneException) {

         e.preventDefault();

         $('#myButton').addClass('ui-state-disabled');

      }

   });

})();

apply the disabled attribute via jQuery

Make a button disabled:

this.att('disabled','disabled');

 
 

Get rid of the disabling:

this.removeAtt('disabled');

jquery.validate and .rules

Jitendra wrote something cool which I assume is empowered by jquery.validate-vsdoc.js. It is:

$.validator.addMethod(

   "compareDate",

   function (value, element, comparewith) {

      if (value != '')

         var date1 = Globalize.parseDate(value, textBoxDateFormat).getTime();

      if (comparewith != '')

         var date2 = Globalize.parseDate(comparewith, textBoxDateFormat).getTime();

         

      if (date1 != undefined && date2 != undefined)

         return !(date1 > date2)

      else

         return false;

   }

);

 
 

It is implemented in jQuery like so:

var firstShipDateField = $('#SiliconSampleDefinition_FirstShipDate');

var lastShipDateField = $('#SiliconSampleDefinition_LastShipDate');

if (firstShipDateField.val() == '') {

   firstShipDateField.rules("remove");

} else {

   firstShipDateField.rules("add", {

      compareDate: lastShipDateField.val(),

      messages: { compareDate: "I'm Angry!" }

   });

}

 
 

On the C# side we will have:

@Html.CalendarFor(model => model.Foo.FirstShipDate, "/calendar.gif")

@Html.ValidationMessageFor(model => model.Foo.FirstShipDate)

 
 

The ValidationMessageFor will end up displaying "I'm Angry."

The Remote Validator in MVC3

Two-thirds of the way down the page here is a how-to on The Remote Validator which is an MVC3 way to reach out to a C# method by way of AJAX to undertake complicated form field validations. We discussed using this for a problem today.

Security

We have a class in our app called AccessMap that sort of looks like this:

using System;

using System.Collections.Generic;

using System.Reflection;

   

namespace OurApp.Core.Security

{

   public class AccessMap

   {

      public List<string> Roles { get; set; }

      public List<Guid> IdsOfTeamMemberAccounts { get; set; }

      public List<Guid> IdsOfViewedAccounts { get; set; }

      

      public AccessMap()

      {

      }

   }

}

 
 

...only it has a lot more getsetters. 37 altogether. The getsetters are populated when the application spins up and then the AccessMap is referenced whenever relevant. If showing a list of "Team Member Accounts" and filtering down records shown by items permissioned to the user at hand, one may sanity check against the IdsOfTeamMemberAccounts in lieu of making a trip to the database. The AccessMap is cached in session.

The downside: lag when spinning up the app

The cure? I don't know. Perhaps we will populate portions of the AccessMap progressively as need be. Does anyone know a better way to approach this problem?

Wijmo mistake

http://wijmo.com/ is made by ComponentOne and not Telerik. I was mistaken.

backing store

A backing store is a control that will be submitted in a form. A backing store may be a hidden field or a field invisible by way of CSS or a control that masquerades as just one piece of a set of controls. Different controls take in user data, then jQuery/JavaScript update the backing store where the collected data will ultimately be submitted from.

Wijmo Telerik Controls

...are apparently build on jQuery UI controls. (so I hear)

 

Update! This posting is a mistake, yet it keeps getting traffic. Please see: http://tom-jaeschke.blogspot.com/2011/12/wijmo-mistake.html