Monday, April 16, 2012

How to setup email in Sharepoint 2010 on a Windows 2008 R2 Server (relay to gmail)

  • Use Server Manager to add SMTP server feature
  • Launch IIS 6.0 admin console
  • SMTP Server Properties
    • Allow relay
    • TLS for Delivery
    • Port 587
    • smtp.gmail.com as "smart host"
    • your domain as FDQN
    • Basic authentication with gmail address as user name and its associated password
  • Use Sharepoint Central Adminstration to set the SMTP server

Friday, April 13, 2012

What's a Thread?

One of the challenges for beginner programmers is adapting to the vocabulary in their field. 

The first time I heard the term "multi threaded" I had absoolutely no clue.  Looking up the definition didn't help much either.  At the time, I simply couldn't get over the feeling of being out of my depth.

Although it was a number of years ago, I suppose the same thing happens to beginning computer programmers.  I bet a good number of them up reading a definition similar to the following from Wikipedia at the time of this writing:
In computer science, a thread of execution is the smallest unit of processing that can be scheduled by an operating system. The implementation of threads and processes differs from one operating system to another, but in most cases, a thread is contained inside a process. Multiple threads can exist within the same process and share resources such as memory, while different processes do not share these resources. In particular, the threads of a process share the latter's instructions (its code) and its context (the values that its variables reference at any given moment). To give an analogy, multiple threads in a process are like multiple cooks reading off the same cook book and following its instructions, not necessarily from the same page.

On a single processor, multithreading generally occurs by time-division multiplexing (as in multitasking): the processor switches between different threads. This context switching generally happens frequently enough that the user perceives the threads or tasks as running at the same time. On a multiprocessor (including multi-core system), the threads or tasks will actually run at the same time, with each processor or core running a particular thread or task.
Many modern operating systems directly support both time-sliced and multiprocessor threading with a process scheduler. The kernel of an operating system allows programmers to manipulate threads via the system call interface. Some implementations are called a kernel thread, whereas a lightweight process (LWP) is a specific type of kernel thread that shares the same state and information.

Why isn't the above definition very useful to beginners and only marginally useful to anyone else?

In my opinion, these kinds of definitions are not very useful to anybody because if you can comprehend it then you are already higher up on the learning curve that anyone who would actually need it in the first place.
The problem is that an understanding of threads is not the result of processing the words that make up its definition.  Rather it comes from an understanding of the environment that naturally gives rise to their existance.

How can this be improved upon?
Here's a first stab at a more concise way to saying all this.  The main difference is taht I try to use only words that a beginner would understand. 
  • Computers run programs one instruction at a time.
  • An operating system is a special program that orchestrates the execution of multiple other programs by organizing their instructions in memory and switching rapidly between them at a rate that gives the user an effect of simultaneous execution.
  • A thread is to a process as a process is to an operating system.
It is still up to the student to have a fair amount of mental acuity to process a more abstract description particularly the use of an analogy, so I'm not entirely sure this is an improvement but I do think it's in the direction of one.


Thursday, April 12, 2012

How To Create an Updateable View in SQL Server

Relational databases typically break information into multiple tables to reduce the amount of repeated information they contain.

For example suppose you want to store notes about people.
You could (but probably should not) create a table like this:

create table PeopleNotes (
   name varchar(max)
  ,note varchar(max)
)

The reason this is a bad idea becomes clear when you consider the contents of the table when multiple notes are entered for the same person.

insert into PeopleNotes values
  ('Aaron', 'came to work')
 ,('Joe', 'left eary')
 ,('Aaron', 'posted to his blog')


name     note
-------  -------------
Aaron    came to work
Joe      left eary
Aaron    posted to his blog



The problem with the data in PeopleNotes is that the name "Aaron" is stored two times.  This doesn't seem like a big deal but if there were 1,000,000 notes then it would waste alot of space to repeat those 5 characters of the name over and over for each row.

The solution is to make a second table called People and then change PeopleNotes to store a reference to its id.

create table People (
   id int primary key not null identity(1,1)
  ,name varchar(max)
)


create table PeopleNotes (
   id int primary key not null identity(1,1)
   person_id varchar(max) references People(id)
  ,note varchar(max)
)



id      name
------- -------------
1       Aaron
2       Joe


id      person_id note
------- --------- -------------
1       1         came to work
2       2         left eary
3       1         Aaron posted to his blog


The extra complexity of a second table yields a savings every time a note is added for person that already exists because instead of storing all the characters of the name it just has to store the id of row in the Person table.

Now in order to get the same result a view is created to join the tables together.

create view v_PeopleNotes as
select P.name, N.note
from PeopleNotes N
inner join People P on N.person_id = P.id


The complexity of inserting increases since in order to add a row to PeopleNotes, the People table needs to be checked for the existance of the person's name and added to if not found.

By placing the required logic in an INSTEAD OF INSERT trigger, the insert statement that originally worked with PeopleNotes when it was a single table now works with v_PeopleNotes.

create trigger tr_v_PeopleNotes_IOI on v_PeopleNotes
instead of insert as begin
    set nocount on

    --
    -- insert People
    --
    if(not exists(
      select P.id from People P
      inner join inserted I on P.name = I.name))
         insert into People

         select distinct name from inserted
    --
    -- insert PeopleNotes
    -- 
    insert into PeopleNotes (person_id, note)
    select P.id, I.note
    from People P inner join inserted I on P.name = I.name
end

Tuesday, April 10, 2012

Enterprise Library 5.0 Logging Step by Step Quick Start


Environment / Setup

  • Visual Studio 2010 Professional
  • Visual Studio Extension – NuGet Package Manager
  • Visual Studio Extension – EnterpriseLibrary.Config

Step 1 – Create a console application.

Step 2 – Use NuGet package manager to add the Enterprise Library 5.0 logging assemblies to your project.

  • Open the Package Manager Console
  • Set the package manager default project to your console application.
  • Issue the following package manager command:
    PM> install-package EnterpriseLibrary.Logging

Step 3 – Add an application configuration item (App.config) to your console application.

Step 4 – Configure Enterprise Library 5.0 logging.

  • Launch the Enterprise Library configuration editor.
  • Click BlocksàAdd Logging Settings
  • Save and exit.

Step 5 – Code a log entry.

var logEntry = new Microsoft.Practices.EnterpriseLibrary.Logging.LogEntry();
logEntry.Message = "test log entry 1";
Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Write(logEntry);

Step 6 – Try it out.

  • Run the application.
  • Run eventvwr.exe