<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://homeostasis.scs.carleton.ca/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Leah</id>
	<title>Soma-notes - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://homeostasis.scs.carleton.ca/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Leah"/>
	<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php/Special:Contributions/Leah"/>
	<updated>2026-04-06T12:04:16Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.42.1</generator>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_17&amp;diff=18985</id>
		<title>WebFund 2014W Lecture 17</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_17&amp;diff=18985"/>
		<updated>2014-04-04T02:55:19Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on March 14, 2014 is available:&lt;br /&gt;
&lt;br /&gt;
* [http://www.screencast.com/t/cSo3EOTe Small from screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/cFqe9HmJc8t6 Large from screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Lecture_17_-_20140314_142511_27.mp4 Original from CUOL]&lt;br /&gt;
&lt;br /&gt;
[http://homeostasis.scs.carleton.ca/~soma/webfund-2014w/adventure-editor-class.zip adventure-editor-class] is also available (without modules, you&#039;ll have to run &amp;quot;npm install&amp;quot; or copy node_modules from adventure-editor or similar application).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Assignment 3 Tips ===&lt;br /&gt;
&amp;quot;Load&amp;quot; button tips:&lt;br /&gt;
* We need to create editor.js and update getContents.&lt;br /&gt;
&lt;br /&gt;
The following client-side code is created in editor.js. When the user click on the load button, the $.getJSON call specifies getContents as the url to send the request to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  $(function(){&lt;br /&gt;
    var updateRoom = function(room) {&lt;br /&gt;
      $(&#039;#roomTitle&#039;).html(room.title);&lt;br /&gt;
      $(&#039;#description&#039;).html(room.description);&lt;br /&gt;
         if (room.activity) {&lt;br /&gt;
            $(&#039;#activity&#039;).html(room.activity);&lt;br /&gt;
         } else {&lt;br /&gt;
            $(&#039;#activity&#039;).html(&amp;quot;&amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
         $(&#039;#exits&#039;).html(room.roomExits + &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    $(&amp;quot;#loadRoom&amp;quot;).on(&amp;quot;click&amp;quot;,function(){&lt;br /&gt;
       $.getJSON(&amp;quot;/getContents&amp;quot;,&lt;br /&gt;
            { theRoom: $(&amp;quot;#roomName&amp;quot;).val()},&lt;br /&gt;
              updateRoom);&lt;br /&gt;
       });&lt;br /&gt;
  });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*In index.js, the function getContents handles the request find the room in the roomsCollection and loads the queried room&lt;br /&gt;
		&lt;br /&gt;
  var getContents = function(req, res) {&lt;br /&gt;
    var theRoom;&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
      theRoom = req.session.player.room;&lt;br /&gt;
    } else if (req.session.editorName) {&lt;br /&gt;
      theRoom = req.query.theRoom;&lt;br /&gt;
    } else {&lt;br /&gt;
      console.log(&amp;quot;Invalid getContents request.&amp;quot;);&lt;br /&gt;
      res.send(&amp;quot;Error: NotLoggedIn&amp;quot;);&lt;br /&gt;
      return;&lt;br /&gt;
     }&lt;br /&gt;
     roomsCollection.findOne(&lt;br /&gt;
     {name: theRoom},&lt;br /&gt;
     function(err, room) {&lt;br /&gt;
        if (err || !room) {&lt;br /&gt;
          room = defaultRoom;&lt;br /&gt;
        }&lt;br /&gt;
       res.send(room); &lt;br /&gt;
     }&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Save&amp;quot; button tips:&lt;br /&gt;
* The current save button does a POST to /updateRooms. &lt;br /&gt;
* It already works and sends everything. All we need to do is implement updateRoom on the server side.&lt;br /&gt;
* &amp;quot;Cannot POST /updateRoom&amp;quot; means we don&#039;t have a route to updateRoom, so we would need to create one and write a function for updateRoom.&lt;br /&gt;
* After the room is saved we should decide what happens after, such as having a page that says &amp;quot;Room saved&amp;quot; and takes you back to the editor.&lt;br /&gt;
&lt;br /&gt;
Drop down button tips:&lt;br /&gt;
* We could use a table, or just a simple button drop down using Bootstrap.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== HTML Canvas Element ===&lt;br /&gt;
&lt;br /&gt;
* Part of HTML5&lt;br /&gt;
*  scriptable rendering of 2D shapes and bitmap images&lt;br /&gt;
* We first set up a HTML canvas widget&lt;br /&gt;
* Give it a name (ID), and dimensions&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;canvas id=&amp;quot;example&amp;quot; width=&amp;quot;200&amp;quot; height=&amp;quot;200&amp;quot;&amp;gt;&lt;br /&gt;
  We put some text here to display if browser does not support HTML5 canvas.&lt;br /&gt;
  &amp;lt;/canvas&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* We can use Javascript to draw on the canvas. &lt;br /&gt;
*The following code draws a red box and circle on the screen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  &amp;lt;script&amp;gt;&lt;br /&gt;
    var example = document.getElementById(&#039;example&#039;);&lt;br /&gt;
    var context = example.getContext(&#039;2d&#039;);&lt;br /&gt;
    context.fillStyle = &#039;red&#039;;&lt;br /&gt;
    context.fillRect(30, 30, 50, 50)&lt;br /&gt;
    //The following code draws a circle.&lt;br /&gt;
    context.beginPath();&lt;br /&gt;
    context.arc(100, 75, 50, 0, 2 *Math.PI);&lt;br /&gt;
    context.stroke();&lt;br /&gt;
  &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Drawing a arc is similar in languages such as Processing.&lt;br /&gt;
* Arcs are defined by a center point, a radius, a starting angle, an ending angle, and the drawing direction (either clockwise or anticlockwise).&lt;br /&gt;
&lt;br /&gt;
* To use JQuery, we need to add it in the &amp;lt;head&amp;gt;&lt;br /&gt;
  &amp;lt;script src=&amp;quot;http://code.jquery.com/jquery-1.11.0.min,js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* We can now use JQuery and write &lt;br /&gt;
    var example = $(&#039;example&#039;);&lt;br /&gt;
    var context = example[0].getContext(&#039;2d&#039;);&lt;br /&gt;
&lt;br /&gt;
* To use javascript we need to get the canvas object.&lt;br /&gt;
* We have to get the standard object out of the JQuery object (what the [0] is).&lt;br /&gt;
* Must use getContext(). In this case the parameter is &amp;quot;2d&amp;quot;, we could also use 3d (WebGL) and others.&lt;br /&gt;
* Then we can use context.arc, context.fillStyle etc. for example to drawing things.&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_17&amp;diff=18984</id>
		<title>WebFund 2014W Lecture 17</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_17&amp;diff=18984"/>
		<updated>2014-04-04T02:54:33Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on March 14, 2014 is available:&lt;br /&gt;
&lt;br /&gt;
* [http://www.screencast.com/t/cSo3EOTe Small from screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/cFqe9HmJc8t6 Large from screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Lecture_17_-_20140314_142511_27.mp4 Original from CUOL]&lt;br /&gt;
&lt;br /&gt;
[http://homeostasis.scs.carleton.ca/~soma/webfund-2014w/adventure-editor-class.zip adventure-editor-class] is also available (without modules, you&#039;ll have to run &amp;quot;npm install&amp;quot; or copy node_modules from adventure-editor or similar application).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Assignment 3 Tips ===&lt;br /&gt;
&amp;quot;Load&amp;quot; button tips:&lt;br /&gt;
* We need to create editor.js and update getContents.&lt;br /&gt;
&lt;br /&gt;
The following client-side code is created in editor.js. When the user click on the load button, the $.getJSON call specifies getContents as the url to send the request to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  $(function(){&lt;br /&gt;
    var updateRoom = function(room) {&lt;br /&gt;
      $(&#039;#roomTitle&#039;).html(room.title);&lt;br /&gt;
      $(&#039;#description&#039;).html(room.description);&lt;br /&gt;
         if (room.activity) {&lt;br /&gt;
            $(&#039;#activity&#039;).html(room.activity);&lt;br /&gt;
         } else {&lt;br /&gt;
            $(&#039;#activity&#039;).html(&amp;quot;&amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
         $(&#039;#exits&#039;).html(room.roomExits + &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    $(&amp;quot;#loadRoom&amp;quot;).on(&amp;quot;click&amp;quot;,function(){&lt;br /&gt;
       $.getJSON(&amp;quot;/getContents&amp;quot;,&lt;br /&gt;
            { theRoom: $(&amp;quot;#roomName&amp;quot;).val()},&lt;br /&gt;
              updateRoom);&lt;br /&gt;
       });&lt;br /&gt;
  });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*In index.js, the function getContents handles the request find the room in the roomsCollection and loads the queried room&lt;br /&gt;
		&lt;br /&gt;
  var getContents = function(req, res) {&lt;br /&gt;
    var theRoom;&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
      theRoom = req.session.player.room;&lt;br /&gt;
    } else if (req.session.editorName) {&lt;br /&gt;
      theRoom = req.query.theRoom;&lt;br /&gt;
    } else {&lt;br /&gt;
      console.log(&amp;quot;Invalid getContents request.&amp;quot;);&lt;br /&gt;
      res.send(&amp;quot;Error: NotLoggedIn&amp;quot;);&lt;br /&gt;
      return;&lt;br /&gt;
     }&lt;br /&gt;
     roomsCollection.findOne(&lt;br /&gt;
     {name: theRoom},&lt;br /&gt;
     function(err, room) {&lt;br /&gt;
        if (err || !room) {&lt;br /&gt;
          room = defaultRoom;&lt;br /&gt;
        }&lt;br /&gt;
       res.send(room); &lt;br /&gt;
     }&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Save&amp;quot; button tips:&lt;br /&gt;
* The current save button does a POST to /updateRooms. &lt;br /&gt;
* It already works and sends everything. All we need to do is implement updateRoom on the server side.&lt;br /&gt;
* &amp;quot;Cannot POST /updateRoom&amp;quot; means we don&#039;t have a route to updateRoom, so we would need to create one and write a function for updateRoom.&lt;br /&gt;
* After the room is saved we should decide what happens after, such as having a page that says &amp;quot;Room saved&amp;quot; and takes you back to the editor.&lt;br /&gt;
&lt;br /&gt;
Drop down button tips:&lt;br /&gt;
* We could use a table, or just a simple button drop down using Bootstrap.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== HTML Canvas Element ===&lt;br /&gt;
&lt;br /&gt;
* Part of HTML5&lt;br /&gt;
*  scriptable rendering of 2D shapes and bitmap images&lt;br /&gt;
* We first set up a HTML canvas widget&lt;br /&gt;
* Give it a name (ID), and dimensions&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;canvas id=&amp;quot;example&amp;quot; width=&amp;quot;200&amp;quot; height=&amp;quot;200&amp;quot;&amp;gt;&lt;br /&gt;
  We put some text here to display if browser does not support HTML5 canvas.&lt;br /&gt;
  &amp;lt;/canvas&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* We can use Javascript to draw on the canvas. &lt;br /&gt;
*The following code draws a red box on the screen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  &amp;lt;script&amp;gt;&lt;br /&gt;
    var example = document.getElementById(&#039;example&#039;);&lt;br /&gt;
    var context = example.getContext(&#039;2d&#039;);&lt;br /&gt;
    context.fillStyle = &#039;red&#039;;&lt;br /&gt;
    context.fillRect(30, 30, 50, 50)&lt;br /&gt;
    //The following code draws a circle.&lt;br /&gt;
    context.beginPath();&lt;br /&gt;
    context.arc(100, 75, 50, 0, 2 *Math.PI);&lt;br /&gt;
    context.stroke();&lt;br /&gt;
  &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Drawing a arc is similar in languages such as Processing.&lt;br /&gt;
* Arcs are defined by a center point, a radius, a starting angle, an ending angle, and the drawing direction (either clockwise or anticlockwise).&lt;br /&gt;
&lt;br /&gt;
* To use JQuery, we need to add it in the &amp;lt;head&amp;gt;&lt;br /&gt;
  &amp;lt;script src=&amp;quot;http://code.jquery.com/jquery-1.11.0.min,js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* We can now use JQuery and write &lt;br /&gt;
    var example = $(&#039;example&#039;);&lt;br /&gt;
    var context = example[0].getContext(&#039;2d&#039;);&lt;br /&gt;
&lt;br /&gt;
* To use javascript we need to get the canvas object.&lt;br /&gt;
* We have to get the standard object out of the JQuery object (what the [0] is).&lt;br /&gt;
* Must use getContext(). In this case the parameter is &amp;quot;2d&amp;quot;, we could also use 3d (WebGL) and others.&lt;br /&gt;
* Then we can use context.arc, context.fillStyle etc. for example to drawing things.&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_17&amp;diff=18983</id>
		<title>WebFund 2014W Lecture 17</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_17&amp;diff=18983"/>
		<updated>2014-04-04T02:53:52Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on March 14, 2014 is available:&lt;br /&gt;
&lt;br /&gt;
* [http://www.screencast.com/t/cSo3EOTe Small from screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/cFqe9HmJc8t6 Large from screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Lecture_17_-_20140314_142511_27.mp4 Original from CUOL]&lt;br /&gt;
&lt;br /&gt;
[http://homeostasis.scs.carleton.ca/~soma/webfund-2014w/adventure-editor-class.zip adventure-editor-class] is also available (without modules, you&#039;ll have to run &amp;quot;npm install&amp;quot; or copy node_modules from adventure-editor or similar application).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Assignment 3 Tips ===&lt;br /&gt;
&amp;quot;Load&amp;quot; button tips:&lt;br /&gt;
* We need to create editor.js and update getContents.&lt;br /&gt;
&lt;br /&gt;
The following client-side code is created in editor.js. When the user click on the load button, the $.getJSON call specifies getContents as the url to send the request to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  $(function(){&lt;br /&gt;
    var updateRoom = function(room) {&lt;br /&gt;
      $(&#039;#roomTitle&#039;).html(room.title);&lt;br /&gt;
      $(&#039;#description&#039;).html(room.description);&lt;br /&gt;
         if (room.activity) {&lt;br /&gt;
            $(&#039;#activity&#039;).html(room.activity);&lt;br /&gt;
         } else {&lt;br /&gt;
            $(&#039;#activity&#039;).html(&amp;quot;&amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
         $(&#039;#exits&#039;).html(room.roomExits + &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    $(&amp;quot;#loadRoom&amp;quot;).on(&amp;quot;click&amp;quot;,function(){&lt;br /&gt;
       $.getJSON(&amp;quot;/getContents&amp;quot;,&lt;br /&gt;
            { theRoom: $(&amp;quot;#roomName&amp;quot;).val()},&lt;br /&gt;
              updateRoom);&lt;br /&gt;
       });&lt;br /&gt;
  });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*In index.js, the function getContents handles the request find the room in the roomsCollection and loads the queried room&lt;br /&gt;
		&lt;br /&gt;
  var getContents = function(req, res) {&lt;br /&gt;
    var theRoom;&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
      theRoom = req.session.player.room;&lt;br /&gt;
    } else if (req.session.editorName) {&lt;br /&gt;
      theRoom = req.query.theRoom;&lt;br /&gt;
    } else {&lt;br /&gt;
      console.log(&amp;quot;Invalid getContents request.&amp;quot;);&lt;br /&gt;
      res.send(&amp;quot;Error: NotLoggedIn&amp;quot;);&lt;br /&gt;
      return;&lt;br /&gt;
     }&lt;br /&gt;
     roomsCollection.findOne(&lt;br /&gt;
     {name: theRoom},&lt;br /&gt;
     function(err, room) {&lt;br /&gt;
        if (err || !room) {&lt;br /&gt;
          room = defaultRoom;&lt;br /&gt;
        }&lt;br /&gt;
       res.send(room); &lt;br /&gt;
     }&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Save&amp;quot; button tips:&lt;br /&gt;
* The current save button does a POST to /updateRooms. &lt;br /&gt;
* It already works and sends everything. All we need to do is implement updateRoom on the server side.&lt;br /&gt;
* &amp;quot;Cannot POST /updateRoom&amp;quot; means we don&#039;t have a route to updateRoom, so we would need to create one and write a function for updateRoom.&lt;br /&gt;
* After the room is saved we should decide what happens after, such as having a page that says &amp;quot;Room saved&amp;quot; and takes you back to the editor.&lt;br /&gt;
&lt;br /&gt;
Drop down button tips:&lt;br /&gt;
* We could use a table, or just a simple button drop down using Bootstrap.&lt;br /&gt;
&lt;br /&gt;
=== HTML Canvas Element ===&lt;br /&gt;
&lt;br /&gt;
* Part of HTML5&lt;br /&gt;
*  scriptable rendering of 2D shapes and bitmap images&lt;br /&gt;
* We first set up a HTML canvas widget&lt;br /&gt;
* Give it a name (ID), and dimensions&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;canvas id=&amp;quot;example&amp;quot; width=&amp;quot;200&amp;quot; height=&amp;quot;200&amp;quot;&amp;gt;&lt;br /&gt;
  We put some text here to display if browser does not support HTML5 canvas.&lt;br /&gt;
  &amp;lt;/canvas&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* We can use Javascript to draw on the canvas. &lt;br /&gt;
*The following code draws a red box on the screen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  &amp;lt;script&amp;gt;&lt;br /&gt;
    var example = document.getElementById(&#039;example&#039;);&lt;br /&gt;
    var context = example.getContext(&#039;2d&#039;);&lt;br /&gt;
    context.fillStyle = &#039;red&#039;;&lt;br /&gt;
    context.fillRect(30, 30, 50, 50)&lt;br /&gt;
    //The following code draws a circle.&lt;br /&gt;
    context.beginPath();&lt;br /&gt;
    context.arc(100, 75, 50, 0, 2 *Math.PI);&lt;br /&gt;
    context.stroke();&lt;br /&gt;
  &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Drawing a arc is similar in languages such as Processing.&lt;br /&gt;
* Arcs are defined by a center point, a radius, a starting angle, an ending angle, and the drawing direction (either clockwise or anticlockwise).&lt;br /&gt;
&lt;br /&gt;
* To use JQuery, we need to add it in the &amp;lt;head&amp;gt;&lt;br /&gt;
  &amp;lt;script src=&amp;quot;http://code.jquery.com/jquery-1.11.0.min,js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* We can now use JQuery and write &lt;br /&gt;
    var example = $(&#039;example&#039;);&lt;br /&gt;
    var context = example[0].getContext(&#039;2d&#039;);&lt;br /&gt;
&lt;br /&gt;
* To use javascript we need to get the canvas object.&lt;br /&gt;
* We have to get the standard object out of the JQuery object (what the [0] is).&lt;br /&gt;
* Must use getContext(). In this case the parameter is &amp;quot;2d&amp;quot;, we could also use 3d (WebGL) and others.&lt;br /&gt;
* Then we can use context.arc, context.fillStyle etc. for example to drawing things.&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_17&amp;diff=18982</id>
		<title>WebFund 2014W Lecture 17</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_17&amp;diff=18982"/>
		<updated>2014-04-04T02:52:21Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on March 14, 2014 is available:&lt;br /&gt;
&lt;br /&gt;
* [http://www.screencast.com/t/cSo3EOTe Small from screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/cFqe9HmJc8t6 Large from screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Lecture_17_-_20140314_142511_27.mp4 Original from CUOL]&lt;br /&gt;
&lt;br /&gt;
[http://homeostasis.scs.carleton.ca/~soma/webfund-2014w/adventure-editor-class.zip adventure-editor-class] is also available (without modules, you&#039;ll have to run &amp;quot;npm install&amp;quot; or copy node_modules from adventure-editor or similar application).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Assignment 3 Tips ===&lt;br /&gt;
&amp;quot;Load&amp;quot; button tips:&lt;br /&gt;
* We need to create editor.js and update getContents.&lt;br /&gt;
&lt;br /&gt;
The following client-side code is created in editor.js. When the user click on the load button, the $.getJSON call specifies getContents as the url to send the request to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  $(function(){&lt;br /&gt;
    var updateRoom = function(room) {&lt;br /&gt;
      $(&#039;#roomTitle&#039;).html(room.title);&lt;br /&gt;
      $(&#039;#description&#039;).html(room.description);&lt;br /&gt;
         if (room.activity) {&lt;br /&gt;
            $(&#039;#activity&#039;).html(room.activity);&lt;br /&gt;
         } else {&lt;br /&gt;
            $(&#039;#activity&#039;).html(&amp;quot;&amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
         $(&#039;#exits&#039;).html(room.roomExits + &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    $(&amp;quot;#loadRoom&amp;quot;).on(&amp;quot;click&amp;quot;,function(){&lt;br /&gt;
       $.getJSON(&amp;quot;/getContents&amp;quot;,&lt;br /&gt;
            { theRoom: $(&amp;quot;#roomName&amp;quot;).val()},&lt;br /&gt;
              updateRoom);&lt;br /&gt;
       });&lt;br /&gt;
  });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*In index.js, the function getContents handles the request find the room in the roomsCollection and loads the queried room&lt;br /&gt;
		&lt;br /&gt;
  var getContents = function(req, res) {&lt;br /&gt;
    var theRoom;&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
      theRoom = req.session.player.room;&lt;br /&gt;
    } else if (req.session.editorName) {&lt;br /&gt;
      theRoom = req.query.theRoom;&lt;br /&gt;
    } else {&lt;br /&gt;
      console.log(&amp;quot;Invalid getContents request.&amp;quot;);&lt;br /&gt;
      res.send(&amp;quot;Error: NotLoggedIn&amp;quot;);&lt;br /&gt;
      return;&lt;br /&gt;
     }&lt;br /&gt;
     roomsCollection.findOne(&lt;br /&gt;
     {name: theRoom},&lt;br /&gt;
     function(err, room) {&lt;br /&gt;
        if (err || !room) {&lt;br /&gt;
          room = defaultRoom;&lt;br /&gt;
        }&lt;br /&gt;
       res.send(room); &lt;br /&gt;
     }&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Save&amp;quot; button tips:&lt;br /&gt;
* The current save button does a POST to /updateRooms. &lt;br /&gt;
* It already works and sends everything. All we need to do is implement updateRoom on the server side.&lt;br /&gt;
* &amp;quot;Cannot POST /updateRoom&amp;quot; mean we don&#039;t have a route to updateRoom, so we would need to create one and write a function for updateRoom.&lt;br /&gt;
* After the room is saved we should decide what happens after, such as having a page that says &amp;quot;Room saved&amp;quot; and takes you back to the editor.&lt;br /&gt;
&lt;br /&gt;
Drop down button tips:&lt;br /&gt;
* We could use a table, or just a simple button drop down using Bootstrap.&lt;br /&gt;
&lt;br /&gt;
=== HTML Canvas Element ===&lt;br /&gt;
&lt;br /&gt;
* Part of HTML5&lt;br /&gt;
*  scriptable rendering of 2D shapes and bitmap images&lt;br /&gt;
* We first set up a HTML canvas widget&lt;br /&gt;
* Give it a name (ID), and dimensions&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;canvas id=&amp;quot;example&amp;quot; width=&amp;quot;200&amp;quot; height=&amp;quot;200&amp;quot;&amp;gt;&lt;br /&gt;
  We put some text here to display if browser does not support HTML5 canvas.&lt;br /&gt;
  &amp;lt;/canvas&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* We can use Javascript to draw on the canvas. &lt;br /&gt;
*The following code draws a red box on the screen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  &amp;lt;script&amp;gt;&lt;br /&gt;
    var example = document.getElementById(&#039;example&#039;);&lt;br /&gt;
    var context = example.getContext(&#039;2d&#039;);&lt;br /&gt;
    context.fillStyle = &#039;red&#039;;&lt;br /&gt;
    context.fillRect(30, 30, 50, 50)&lt;br /&gt;
    //The following code draws a circle.&lt;br /&gt;
    context.beginPath();&lt;br /&gt;
    context.arc(100, 75, 50, 0, 2 *Math.PI);&lt;br /&gt;
    context.stroke();&lt;br /&gt;
  &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Drawing a arc is similar in languages such as Processing.&lt;br /&gt;
* Arcs are defined by a center point, a radius, a starting angle, an ending angle, and the drawing direction (either clockwise or anticlockwise).&lt;br /&gt;
&lt;br /&gt;
* To use JQuery, we need to add it in the &amp;lt;head&amp;gt;&lt;br /&gt;
  &amp;lt;script src=&amp;quot;http://code.jquery.com/jquery-1.11.0.min,js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* We can now use JQuery and write &lt;br /&gt;
    var example = $(&#039;example&#039;);&lt;br /&gt;
    var context = example[0].getContext(&#039;2d&#039;);&lt;br /&gt;
&lt;br /&gt;
* To use javascript we need to get the canvas object.&lt;br /&gt;
* We have to get the standard object out of the JQuery object (what the [0] is).&lt;br /&gt;
* Must use getContext(). In this case the parameter is &amp;quot;2d&amp;quot;, we could also use 3d (WebGL) and others.&lt;br /&gt;
* Then we can use context.arc, context.fillStyle etc. for example to drawing things.&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_17&amp;diff=18981</id>
		<title>WebFund 2014W Lecture 17</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_17&amp;diff=18981"/>
		<updated>2014-04-04T01:40:04Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on March 14, 2014 is available:&lt;br /&gt;
&lt;br /&gt;
* [http://www.screencast.com/t/cSo3EOTe Small from screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/cFqe9HmJc8t6 Large from screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Lecture_17_-_20140314_142511_27.mp4 Original from CUOL]&lt;br /&gt;
&lt;br /&gt;
[http://homeostasis.scs.carleton.ca/~soma/webfund-2014w/adventure-editor-class.zip adventure-editor-class] is also available (without modules, you&#039;ll have to run &amp;quot;npm install&amp;quot; or copy node_modules from adventure-editor or similar application).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== HTML Canvas Element ===&lt;br /&gt;
&lt;br /&gt;
* Part of HTML5&lt;br /&gt;
*  scriptable rendering of 2D shapes and bitmap images&lt;br /&gt;
* We first set up a HTML canvas widget&lt;br /&gt;
* Give it a name (ID), and dimensions&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;canvas id=&amp;quot;example&amp;quot; width=&amp;quot;200&amp;quot; height=&amp;quot;200&amp;quot;&amp;gt;&lt;br /&gt;
  We put some text here to display if browser does not support HTML5 canvas.&lt;br /&gt;
  &amp;lt;/canvas&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* We can use Javascript to draw on the canvas. &lt;br /&gt;
*The following code draws a red box on the screen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  &amp;lt;script&amp;gt;&lt;br /&gt;
    var example = document.getElementById(&#039;example&#039;);&lt;br /&gt;
    var context = example.getContext(&#039;2d&#039;);&lt;br /&gt;
    context.fillStyle = &#039;red&#039;;&lt;br /&gt;
    context.fillRect(30, 30, 50, 50)&lt;br /&gt;
    //The following code draws a circle.&lt;br /&gt;
    context.beginPath();&lt;br /&gt;
    context.arc(100, 75, 50, 0, 2 *Math.PI);&lt;br /&gt;
    context.stroke();&lt;br /&gt;
  &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Drawing a arc is similar in languages such as Processing.&lt;br /&gt;
* Arcs are defined by a center point, a radius, a starting angle, an ending angle, and the drawing direction (either clockwise or anticlockwise).&lt;br /&gt;
&lt;br /&gt;
* To use JQuery, we need to add it in the &amp;lt;head&amp;gt;&lt;br /&gt;
  &amp;lt;script src=&amp;quot;http://code.jquery.com/jquery-1.11.0.min,js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* We can now use JQuery and write &lt;br /&gt;
    var example = $(&#039;example&#039;);&lt;br /&gt;
    var context = example[0].getContext(&#039;2d&#039;);&lt;br /&gt;
&lt;br /&gt;
* To use javascript we need to get the canvas object.&lt;br /&gt;
* We have to get the standard object out of the JQuery object (what the [0] is).&lt;br /&gt;
* Must use getContext(). In this case the parameter is &amp;quot;2d&amp;quot;, we could also use 3d (WebGL) and others.&lt;br /&gt;
* Then we can use context.arc, context.fillStyle etc. for example to drawing things.&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_17&amp;diff=18980</id>
		<title>WebFund 2014W Lecture 17</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_17&amp;diff=18980"/>
		<updated>2014-04-04T01:26:45Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on March 14, 2014 is available:&lt;br /&gt;
&lt;br /&gt;
* [http://www.screencast.com/t/cSo3EOTe Small from screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/cFqe9HmJc8t6 Large from screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Lecture_17_-_20140314_142511_27.mp4 Original from CUOL]&lt;br /&gt;
&lt;br /&gt;
[http://homeostasis.scs.carleton.ca/~soma/webfund-2014w/adventure-editor-class.zip adventure-editor-class] is also available (without modules, you&#039;ll have to run &amp;quot;npm install&amp;quot; or copy node_modules from adventure-editor or similar application).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== HTML Canvas Element ===&lt;br /&gt;
&lt;br /&gt;
* Part of HTML5&lt;br /&gt;
*  scriptable rendering of 2D shapes and bitmap images&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;canvas id=&amp;quot;example&amp;quot; width=&amp;quot;200&amp;quot; height=&amp;quot;200&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/canvas&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* We can use Javascript to draw on the canvas. &lt;br /&gt;
*The following code draws a red box on the screen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  &amp;lt;script&amp;gt;&lt;br /&gt;
    var example = document.getElementById(&#039;example&#039;);&lt;br /&gt;
    var context = example.getContext(&#039;2d&#039;);&lt;br /&gt;
    context.fillStyle = &#039;red&#039;;&lt;br /&gt;
    context.fillRect(30, 30, 50, 50)&lt;br /&gt;
    //The following code draws a circle.&lt;br /&gt;
    context.beginPath();&lt;br /&gt;
    context.arc(100, 75, 50, 0, 2 *Math.PI);&lt;br /&gt;
    context.stroke();&lt;br /&gt;
  &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Drawing a arc is similar in languages such as Processing.&lt;br /&gt;
* Arcs are defined by a center point, a radius, a starting angle, an ending angle, and the drawing direction (either clockwise or anticlockwise).&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_17&amp;diff=18979</id>
		<title>WebFund 2014W Lecture 17</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_17&amp;diff=18979"/>
		<updated>2014-04-04T01:20:49Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on March 14, 2014 is available:&lt;br /&gt;
&lt;br /&gt;
* [http://www.screencast.com/t/cSo3EOTe Small from screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/cFqe9HmJc8t6 Large from screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Lecture_17_-_20140314_142511_27.mp4 Original from CUOL]&lt;br /&gt;
&lt;br /&gt;
[http://homeostasis.scs.carleton.ca/~soma/webfund-2014w/adventure-editor-class.zip adventure-editor-class] is also available (without modules, you&#039;ll have to run &amp;quot;npm install&amp;quot; or copy node_modules from adventure-editor or similar application).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
HTML Canvas Element&lt;br /&gt;
* Part of HTML5&lt;br /&gt;
*  scriptable rendering of 2D shapes and bitmap images&lt;br /&gt;
&lt;br /&gt;
&amp;lt;canvas id=&amp;quot;example&amp;quot; width=&amp;quot;200&amp;quot; height=&amp;quot;200&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/canvas&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* We can use Javascript to draw on the canvas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
// The following code draws a red box on the screen.&lt;br /&gt;
var example = document.getElementById(&#039;example&#039;);&lt;br /&gt;
var context = example.getContext(&#039;2d&#039;);&lt;br /&gt;
context.fillStyle = &#039;red&#039;;&lt;br /&gt;
context.fillRect(30, 30, 50, 50)&lt;br /&gt;
&lt;br /&gt;
//The following code draws a circle.&lt;br /&gt;
context.beginPath();&lt;br /&gt;
context.arc(100, 75, 50, 0, 2 *Math.PI);&lt;br /&gt;
context.stroke();&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Drawing a arc is similar in languages such as Processing.&lt;br /&gt;
* Arcs are defined by a center point, a radius, a starting angle, an ending angle, and the drawing direction (either clockwise or anticlockwise).&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Midterm_Review&amp;diff=18833</id>
		<title>WebFund 2014W Midterm Review</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Midterm_Review&amp;diff=18833"/>
		<updated>2014-03-13T18:21:53Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on Feb. 12, 2014 is available:&lt;br /&gt;
* [http://www.screencast.com/t/9bmB5dTEoC small at Screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/nC3DlJrkoqt large at Screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Midterm_Review_-_20140212_150208_27.mp4 Original at CUOL]&lt;br /&gt;
&lt;br /&gt;
The midterm will be based on [http://homeostasis.scs.carleton.ca/~soma/webfund-2014w/midterm/small-adventure.zip small-adventure], a version of &amp;lt;tt&amp;gt;adventure-demo&amp;lt;/tt&amp;gt; that has been simplified by removing the use of cryptography (https and bcrypt) along with a few other minor tweaks to reduce the size of the source code.&lt;br /&gt;
&lt;br /&gt;
No new tutorial this week; however, two TAs/instructors will be in the lab on Thursday 4-5:30 and Friday 8:30-10 to answer last minute questions.&lt;br /&gt;
&lt;br /&gt;
==Midterm Review Notes==&lt;br /&gt;
* Most of the notes are written inline in the source code to make the line it refers to more clear:&lt;br /&gt;
&lt;br /&gt;
What is the state of the system after app,js runs?&lt;br /&gt;
* We don&#039;t know what it is because you only know when the call back is run.&lt;br /&gt;
* app.get/app.post are only run ONCE, before the web server starts listening for incoming connections. It tells the web server what to do when http GET and POST requests are received at specific urls. &lt;br /&gt;
&lt;br /&gt;
Asynchronous vs Synchronous:&lt;br /&gt;
* The analogy that Anil gave was that synchronous is like a 5 year old child waiting for cookies to be baked. He asks &amp;quot;is it ready yet?&amp;quot; every 5 minutes. He&#039;s not doing anything else. Asynchronous is like a 8 year old child, who does something else (e.g. read a book) while he waits for the cookies to be baked&lt;br /&gt;
&lt;br /&gt;
==Source for small-adventure==&lt;br /&gt;
&lt;br /&gt;
===app.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var express = require(&#039;express&#039;); //requires the express module&lt;br /&gt;
var routes = require(&#039;./routes&#039;); //same as (&#039;/routes/index.js&#039;). The require() method returns the exports object&lt;br /&gt;
var path = require(&#039;path&#039;); //imports the path module, or path.join will not be defined&lt;br /&gt;
var http = require(&#039;http&#039;); //requires the http module&lt;br /&gt;
var MongoStore = require(&#039;connect-mongo&#039;)(express);&lt;br /&gt;
&lt;br /&gt;
var app = express(); //creates an express object instance and assigns the app variable to it.&lt;br /&gt;
&lt;br /&gt;
app.set(&#039;port&#039;, process.env.PORT || 3000); //listens on PORT environment variable OR port 3000 if not defined&lt;br /&gt;
app.set(&#039;views&#039;, path.join(__dirname, &#039;views&#039;)); //sets the location for application views&lt;br /&gt;
app.set(&#039;view engine&#039;, &#039;jade&#039;); //sets the view engine, Jade&lt;br /&gt;
app.use(express.favicon()); //can specify where you want favicon to be found in the parameters. e.g (_dirname + &#039;public/favicon.ico&#039;)&lt;br /&gt;
app.use(express.logger(&#039;dev&#039;)); //logging requests using predefined log format &#039;dev&#039;. This will generate a detail log.&lt;br /&gt;
app.use(express.urlencoded()); //The body of HTTP post requests. Parses the incoming request body, converting it into request object properties&lt;br /&gt;
&lt;br /&gt;
app.use(express.cookieParser()); &lt;br /&gt;
app.use(express.session({&lt;br /&gt;
    cookie: {maxAge: 60000 * 20} // 20 minutes&lt;br /&gt;
    , secret: &amp;quot;Shh... I&#039;m a secret&amp;quot; //This is the secret that prevents attackers from creating their own fake session identifiers&lt;br /&gt;
    , store: new MongoStore({db: &amp;quot;adventure-demo&amp;quot;})&lt;br /&gt;
}));&lt;br /&gt;
&lt;br /&gt;
app.use(app.router);&lt;br /&gt;
app.use(express.static(path.join(__dirname, &#039;public&#039;))); //serves static files from the root path. The CSS files and fonts are all stored in the public directory, which is made publicly accessible by this line.&lt;br /&gt;
&lt;br /&gt;
if (&#039;development&#039; == app.get(&#039;env&#039;)) {&lt;br /&gt;
  app.use(express.errorHandler());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//The purpose of these lines is to setup routes. It tells the web server what to do when http GET and POST requests are received at specific urls. Note that these are only run ONCE, before the web server starts listening for incoming connections.&lt;br /&gt;
app.get(&#039;/&#039;, routes.redirectLoggedIn, routes.index); //requests the home page (https://localhost:3000)&lt;br /&gt;
app.post(&amp;quot;/register&amp;quot;, routes.register);&lt;br /&gt;
app.post(&amp;quot;/start&amp;quot;, routes.start);&lt;br /&gt;
app.post(&amp;quot;/quit&amp;quot;, routes.quit);&lt;br /&gt;
&lt;br /&gt;
var createRooms = function() {&lt;br /&gt;
    var i, theRoom;&lt;br /&gt;
&lt;br /&gt;
    routes.getRooms().toArray( //a call to getRooms and a call toArray, which is a method of the collections object. This runs the query and puts the results into an array&lt;br /&gt;
        function(err, docs) {&lt;br /&gt;
            if (err) {&lt;br /&gt;
                throw &amp;quot;Couldn&#039;t find active room list&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            var activeRooms = docs[0].activeRooms;&lt;br /&gt;
&lt;br /&gt;
            activeRooms.forEach(function(roomName) { //roomName is our index variable, we get the room element. ActiveRooms is an array of roomName.&lt;br /&gt;
                console.log(&#039;Creating room: &#039; + roomName);&lt;br /&gt;
                app.get(&#039;/&#039; + roomName,&lt;br /&gt;
                        routes.makeRoomHandler(roomName));&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
routes.connectToDBs(createRooms);&lt;br /&gt;
&lt;br /&gt;
http.createServer(app).listen(app.get(&#039;port&#039;), function(){&lt;br /&gt;
  console.log(&#039;Express server listening on port &#039; + app.get(&#039;port&#039;) +&lt;br /&gt;
              &#039; in &#039; + app.get(&#039;env&#039;) + &#039; mode.&#039;);&lt;br /&gt;
});&lt;br /&gt;
//1) createServer(): a method of http that creates and returns a server object&lt;br /&gt;
//2) listen(): a method at the returned server object that starts the web server listening on a given port&lt;br /&gt;
//3) app.get(): returns the port to listen on&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===routes/index.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var mc = require(&#039;mongodb&#039;).MongoClient;&lt;br /&gt;
var playersCollection, roomsCollection;&lt;br /&gt;
exports.connectToDBs = function(callback) {&lt;br /&gt;
    mc.connect(&#039;mongodb://localhost/adventure-demo&#039;, function(err, db) {&lt;br /&gt;
        if (err) {&lt;br /&gt;
            throw err;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        playersCollection = db.collection(&#039;players&#039;);&lt;br /&gt;
        roomsCollection = db.collection(&#039;rooms&#039;);&lt;br /&gt;
&lt;br /&gt;
        callback(); //is createRooms. We do the callback after the database is established because we need to setup the database first.&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//assigned to the properties of the exports object&lt;br /&gt;
exports.index = function(req, res){&lt;br /&gt;
    res.render(&#039;index&#039;, { title: &#039;COMP 2406 Small Adventure Demo&#039;,&lt;br /&gt;
                          error: req.query.error });&lt;br /&gt;
}&lt;br /&gt;
exports.redirectLoggedIn = function(req, res, next) {&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot; + req.session.player.room);&lt;br /&gt;
    } else {&lt;br /&gt;
        next();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
exports.redirectNotLoggedIn = function(req, res, next) {&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
        next();&lt;br /&gt;
    } else {&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
exports.register = function(req, res) {&lt;br /&gt;
    var playername = req.body.playername; //req.body retrieves the value for the playername attribute&lt;br /&gt;
    var password = req.body.password;&lt;br /&gt;
&lt;br /&gt;
    var addPlayer = function(err, players) {&lt;br /&gt;
        if(players.length!=0){&lt;br /&gt;
            res.redirect(&amp;quot;/?error=player already exists&amp;quot;);      &lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        var newPlayer = {&lt;br /&gt;
            playername: playername,&lt;br /&gt;
            password: password,&lt;br /&gt;
            room: &amp;quot;bridge&amp;quot;&lt;br /&gt;
        };&lt;br /&gt;
                &lt;br /&gt;
        playersCollection.insert(newPlayer, function(err, newPlayers){&lt;br /&gt;
            if (err) {&lt;br /&gt;
                throw err;&lt;br /&gt;
            } else {&lt;br /&gt;
                res.send(&#039;Successfully registered &#039; + newPlayers[0].playername);&lt;br /&gt;
            }&lt;br /&gt;
        });    &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    playersCollection.find({playername: playername}).toArray(addPlayer);&lt;br /&gt;
}&lt;br /&gt;
exports.start = function(req, res){&lt;br /&gt;
    var playername = req.body.playername;&lt;br /&gt;
    var password = req.body.password;&lt;br /&gt;
&lt;br /&gt;
    playersCollection.findOne({playername: playername}, function(err, player) {&lt;br /&gt;
        if (err || !player){&lt;br /&gt;
            req.session.destroy(function(err) {&lt;br /&gt;
                res.redirect(&amp;quot;/?error=invalid playername or password&amp;quot;); &lt;br /&gt;
            });&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (password === player.password) {&lt;br /&gt;
            req.session.player = player;&lt;br /&gt;
            delete req.session.player._id;&lt;br /&gt;
            res.redirect(&amp;quot;/&amp;quot; + player.room);&lt;br /&gt;
        } else {&lt;br /&gt;
            req.session.destroy(function(err) {&lt;br /&gt;
                res.redirect(&amp;quot;/?error=invalid playername or password&amp;quot;);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
exports.quit = function(req, res){&lt;br /&gt;
    req.session.destroy(function(err){&lt;br /&gt;
        if(err){&lt;br /&gt;
            console.log(&amp;quot;Error: %s&amp;quot;, err);&lt;br /&gt;
        }&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
    }); &lt;br /&gt;
}&lt;br /&gt;
exports.makeRoomHandler = function(roomName) {&lt;br /&gt;
    var handler = function(req, res) { //without &#039;var&#039; handler becomes a global variable&lt;br /&gt;
        if (req.session.player) {&lt;br /&gt;
            var player = req.session.player;&lt;br /&gt;
            player.room = roomName;&lt;br /&gt;
            playersCollection.update({&amp;quot;playername&amp;quot;: player.playername},&lt;br /&gt;
                                     player, function(err, count) {&lt;br /&gt;
                                         if (err) {&lt;br /&gt;
                                             console.log(&lt;br /&gt;
                                                 &amp;quot;Couldn&#039;t save player state&amp;quot;);&lt;br /&gt;
                                         }&lt;br /&gt;
                                     });&lt;br /&gt;
            roomsCollection.findOne(&lt;br /&gt;
                {name: roomName},&lt;br /&gt;
                function(err, room) {&lt;br /&gt;
                    if (err || !room) {&lt;br /&gt;
                        throw &amp;quot;Couldn&#039;t find room &amp;quot; + roomName;&lt;br /&gt;
                    }&lt;br /&gt;
                    res.render(&amp;quot;room.jade&amp;quot;, room); //renders an html page with room.jade template&lt;br /&gt;
                }&lt;br /&gt;
            );&lt;br /&gt;
        } else {&lt;br /&gt;
            res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return handler;&lt;br /&gt;
}&lt;br /&gt;
exports.getRooms = function() {&lt;br /&gt;
    return roomsCollection.find({name: &amp;quot;roomList&amp;quot;}); //finds all the rooms with the name in the roomlist&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===public/javascripts/home.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
$(function(){&lt;br /&gt;
	$(&amp;quot;#register&amp;quot;).on(&amp;quot;click&amp;quot;,function(){&lt;br /&gt;
		var $form = $(&amp;quot;form&amp;quot;);&lt;br /&gt;
		$form.attr(&amp;quot;action&amp;quot;,&amp;quot;/register&amp;quot;);&lt;br /&gt;
		$form.submit();&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/layout.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
doctype html&lt;br /&gt;
html&lt;br /&gt;
  head&lt;br /&gt;
    title= title&lt;br /&gt;
    script(src=&#039;/vendor/jquery/jquery.js&#039;)&lt;br /&gt;
    script(&#039;vendor/bootstrap/dist/js/bootstrap.js&#039;)&lt;br /&gt;
    link(rel=&#039;stylesheet&#039;, href=&#039;/vendor/bootstrap/dist/css/bootstrap.css&#039;)&lt;br /&gt;
    link(rel=&#039;stylesheet&#039;, href=&#039;/stylesheets/style.css&#039;)&lt;br /&gt;
    block header  &lt;br /&gt;
  body&lt;br /&gt;
    block content&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/index.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
extends layout //inherits formatting from layout.jade&lt;br /&gt;
&lt;br /&gt;
block header&lt;br /&gt;
  script(src=&#039;/javascripts/home.js&#039;) //applies javascript. Affects the register button&lt;br /&gt;
&lt;br /&gt;
block content&lt;br /&gt;
  h1= title&lt;br /&gt;
  - if(error)&lt;br /&gt;
    div.alert-error #{error}&lt;br /&gt;
  p Please log in&lt;br /&gt;
  div&lt;br /&gt;
    form(action=&amp;quot;/start&amp;quot;, method=&amp;quot;post&amp;quot;)&lt;br /&gt;
        div.control-group.input-append&lt;br /&gt;
            input(type=&amp;quot;text&amp;quot;, name=&amp;quot;playername&amp;quot;)&lt;br /&gt;
            label.add-on(for=&amp;quot;playername&amp;quot;) Player Name&lt;br /&gt;
        div.control-group.input-append&lt;br /&gt;
            input(type=&amp;quot;password&amp;quot;, name=&amp;quot;password&amp;quot;)&lt;br /&gt;
            label.add-on(for=&amp;quot;password&amp;quot;) Password&lt;br /&gt;
            &lt;br /&gt;
        button(type=&amp;quot;submit&amp;quot;) Start&lt;br /&gt;
        button#register(type=&amp;quot;button&amp;quot;) Register&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/room.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
extends layout&lt;br /&gt;
&lt;br /&gt;
block content&lt;br /&gt;
  h1= title&lt;br /&gt;
  p #{description}&lt;br /&gt;
  p Go to:&lt;br /&gt;
  ul&lt;br /&gt;
    each theExit in roomExits //exits are listed for every room&lt;br /&gt;
      li&lt;br /&gt;
        a(href= theExit) #{theExit}&lt;br /&gt;
  form(action=&amp;quot;/quit&amp;quot;, method=&amp;quot;post&amp;quot;)&lt;br /&gt;
     button(type=&amp;quot;submit&amp;quot;) Quit //creates a quit button on every room&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Midterm_Review&amp;diff=18832</id>
		<title>WebFund 2014W Midterm Review</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Midterm_Review&amp;diff=18832"/>
		<updated>2014-03-13T18:21:06Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on Feb. 12, 2014 is available:&lt;br /&gt;
* [http://www.screencast.com/t/9bmB5dTEoC small at Screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/nC3DlJrkoqt large at Screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Midterm_Review_-_20140212_150208_27.mp4 Original at CUOL]&lt;br /&gt;
&lt;br /&gt;
The midterm will be based on [http://homeostasis.scs.carleton.ca/~soma/webfund-2014w/midterm/small-adventure.zip small-adventure], a version of &amp;lt;tt&amp;gt;adventure-demo&amp;lt;/tt&amp;gt; that has been simplified by removing the use of cryptography (https and bcrypt) along with a few other minor tweaks to reduce the size of the source code.&lt;br /&gt;
&lt;br /&gt;
No new tutorial this week; however, two TAs/instructors will be in the lab on Thursday 4-5:30 and Friday 8:30-10 to answer last minute questions.&lt;br /&gt;
&lt;br /&gt;
==Midterm Review Notes==&lt;br /&gt;
* Most of the notes are written inline in the source code to make the line it refers to more clear:&lt;br /&gt;
&lt;br /&gt;
What is the state of the system after app,js runs?&lt;br /&gt;
* We don&#039;t know what it is because you only know when the call back is run.&lt;br /&gt;
* app.get/app.post are only run ONCE, before the web server starts listening for incoming connections. It tells the web server what to do when http GET and POST requests are received at specific urls. &lt;br /&gt;
&lt;br /&gt;
Asynchronous vs Synchronous:&lt;br /&gt;
* The analogy that Anil give was that synchronous is like a 5 year old child waiting for cookies to be baked. He asks &amp;quot;is it ready yet?&amp;quot; every 5 minutes. He&#039;s not doing anything else. Asynchronous is like a 8 year old child, who does something else (e.g. read a book) while he waits for the cookies to be baked&lt;br /&gt;
&lt;br /&gt;
==Source for small-adventure==&lt;br /&gt;
&lt;br /&gt;
===app.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var express = require(&#039;express&#039;); //requires the express module&lt;br /&gt;
var routes = require(&#039;./routes&#039;); //same as (&#039;/routes/index.js&#039;). The require() method returns the exports object&lt;br /&gt;
var path = require(&#039;path&#039;); //imports the path module, or path.join will not be defined&lt;br /&gt;
var http = require(&#039;http&#039;); //requires the http module&lt;br /&gt;
var MongoStore = require(&#039;connect-mongo&#039;)(express);&lt;br /&gt;
&lt;br /&gt;
var app = express(); //creates an express object instance and assigns the app variable to it.&lt;br /&gt;
&lt;br /&gt;
app.set(&#039;port&#039;, process.env.PORT || 3000); //listens on PORT environment variable OR port 3000 if not defined&lt;br /&gt;
app.set(&#039;views&#039;, path.join(__dirname, &#039;views&#039;)); //sets the location for application views&lt;br /&gt;
app.set(&#039;view engine&#039;, &#039;jade&#039;); //sets the view engine, Jade&lt;br /&gt;
app.use(express.favicon()); //can specify where you want favicon to be found in the parameters. e.g (_dirname + &#039;public/favicon.ico&#039;)&lt;br /&gt;
app.use(express.logger(&#039;dev&#039;)); //logging requests using predefined log format &#039;dev&#039;. This will generate a detail log.&lt;br /&gt;
app.use(express.urlencoded()); //The body of HTTP post requests. Parses the incoming request body, converting it into request object properties&lt;br /&gt;
&lt;br /&gt;
app.use(express.cookieParser()); &lt;br /&gt;
app.use(express.session({&lt;br /&gt;
    cookie: {maxAge: 60000 * 20} // 20 minutes&lt;br /&gt;
    , secret: &amp;quot;Shh... I&#039;m a secret&amp;quot; //This is the secret that prevents attackers from creating their own fake session identifiers&lt;br /&gt;
    , store: new MongoStore({db: &amp;quot;adventure-demo&amp;quot;})&lt;br /&gt;
}));&lt;br /&gt;
&lt;br /&gt;
app.use(app.router);&lt;br /&gt;
app.use(express.static(path.join(__dirname, &#039;public&#039;))); //serves static files from the root path. The CSS files and fonts are all stored in the public directory, which is made publicly accessible by this line.&lt;br /&gt;
&lt;br /&gt;
if (&#039;development&#039; == app.get(&#039;env&#039;)) {&lt;br /&gt;
  app.use(express.errorHandler());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//The purpose of these lines is to setup routes. It tells the web server what to do when http GET and POST requests are received at specific urls. Note that these are only run ONCE, before the web server starts listening for incoming connections.&lt;br /&gt;
app.get(&#039;/&#039;, routes.redirectLoggedIn, routes.index); //requests the home page (https://localhost:3000)&lt;br /&gt;
app.post(&amp;quot;/register&amp;quot;, routes.register);&lt;br /&gt;
app.post(&amp;quot;/start&amp;quot;, routes.start);&lt;br /&gt;
app.post(&amp;quot;/quit&amp;quot;, routes.quit);&lt;br /&gt;
&lt;br /&gt;
var createRooms = function() {&lt;br /&gt;
    var i, theRoom;&lt;br /&gt;
&lt;br /&gt;
    routes.getRooms().toArray( //a call to getRooms and a call toArray, which is a method of the collections object. This runs the query and puts the results into an array&lt;br /&gt;
        function(err, docs) {&lt;br /&gt;
            if (err) {&lt;br /&gt;
                throw &amp;quot;Couldn&#039;t find active room list&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            var activeRooms = docs[0].activeRooms;&lt;br /&gt;
&lt;br /&gt;
            activeRooms.forEach(function(roomName) { //roomName is our index variable, we get the room element. ActiveRooms is an array of roomName.&lt;br /&gt;
                console.log(&#039;Creating room: &#039; + roomName);&lt;br /&gt;
                app.get(&#039;/&#039; + roomName,&lt;br /&gt;
                        routes.makeRoomHandler(roomName));&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
routes.connectToDBs(createRooms);&lt;br /&gt;
&lt;br /&gt;
http.createServer(app).listen(app.get(&#039;port&#039;), function(){&lt;br /&gt;
  console.log(&#039;Express server listening on port &#039; + app.get(&#039;port&#039;) +&lt;br /&gt;
              &#039; in &#039; + app.get(&#039;env&#039;) + &#039; mode.&#039;);&lt;br /&gt;
});&lt;br /&gt;
//1) createServer(): a method of http that creates and returns a server object&lt;br /&gt;
//2) listen(): a method at the returned server object that starts the web server listening on a given port&lt;br /&gt;
//3) app.get(): returns the port to listen on&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===routes/index.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var mc = require(&#039;mongodb&#039;).MongoClient;&lt;br /&gt;
var playersCollection, roomsCollection;&lt;br /&gt;
exports.connectToDBs = function(callback) {&lt;br /&gt;
    mc.connect(&#039;mongodb://localhost/adventure-demo&#039;, function(err, db) {&lt;br /&gt;
        if (err) {&lt;br /&gt;
            throw err;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        playersCollection = db.collection(&#039;players&#039;);&lt;br /&gt;
        roomsCollection = db.collection(&#039;rooms&#039;);&lt;br /&gt;
&lt;br /&gt;
        callback(); //is createRooms. We do the callback after the database is established because we need to setup the database first.&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//assigned to the properties of the exports object&lt;br /&gt;
exports.index = function(req, res){&lt;br /&gt;
    res.render(&#039;index&#039;, { title: &#039;COMP 2406 Small Adventure Demo&#039;,&lt;br /&gt;
                          error: req.query.error });&lt;br /&gt;
}&lt;br /&gt;
exports.redirectLoggedIn = function(req, res, next) {&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot; + req.session.player.room);&lt;br /&gt;
    } else {&lt;br /&gt;
        next();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
exports.redirectNotLoggedIn = function(req, res, next) {&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
        next();&lt;br /&gt;
    } else {&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
exports.register = function(req, res) {&lt;br /&gt;
    var playername = req.body.playername; //req.body retrieves the value for the playername attribute&lt;br /&gt;
    var password = req.body.password;&lt;br /&gt;
&lt;br /&gt;
    var addPlayer = function(err, players) {&lt;br /&gt;
        if(players.length!=0){&lt;br /&gt;
            res.redirect(&amp;quot;/?error=player already exists&amp;quot;);      &lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        var newPlayer = {&lt;br /&gt;
            playername: playername,&lt;br /&gt;
            password: password,&lt;br /&gt;
            room: &amp;quot;bridge&amp;quot;&lt;br /&gt;
        };&lt;br /&gt;
                &lt;br /&gt;
        playersCollection.insert(newPlayer, function(err, newPlayers){&lt;br /&gt;
            if (err) {&lt;br /&gt;
                throw err;&lt;br /&gt;
            } else {&lt;br /&gt;
                res.send(&#039;Successfully registered &#039; + newPlayers[0].playername);&lt;br /&gt;
            }&lt;br /&gt;
        });    &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    playersCollection.find({playername: playername}).toArray(addPlayer);&lt;br /&gt;
}&lt;br /&gt;
exports.start = function(req, res){&lt;br /&gt;
    var playername = req.body.playername;&lt;br /&gt;
    var password = req.body.password;&lt;br /&gt;
&lt;br /&gt;
    playersCollection.findOne({playername: playername}, function(err, player) {&lt;br /&gt;
        if (err || !player){&lt;br /&gt;
            req.session.destroy(function(err) {&lt;br /&gt;
                res.redirect(&amp;quot;/?error=invalid playername or password&amp;quot;); &lt;br /&gt;
            });&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (password === player.password) {&lt;br /&gt;
            req.session.player = player;&lt;br /&gt;
            delete req.session.player._id;&lt;br /&gt;
            res.redirect(&amp;quot;/&amp;quot; + player.room);&lt;br /&gt;
        } else {&lt;br /&gt;
            req.session.destroy(function(err) {&lt;br /&gt;
                res.redirect(&amp;quot;/?error=invalid playername or password&amp;quot;);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
exports.quit = function(req, res){&lt;br /&gt;
    req.session.destroy(function(err){&lt;br /&gt;
        if(err){&lt;br /&gt;
            console.log(&amp;quot;Error: %s&amp;quot;, err);&lt;br /&gt;
        }&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
    }); &lt;br /&gt;
}&lt;br /&gt;
exports.makeRoomHandler = function(roomName) {&lt;br /&gt;
    var handler = function(req, res) { //without &#039;var&#039; handler becomes a global variable&lt;br /&gt;
        if (req.session.player) {&lt;br /&gt;
            var player = req.session.player;&lt;br /&gt;
            player.room = roomName;&lt;br /&gt;
            playersCollection.update({&amp;quot;playername&amp;quot;: player.playername},&lt;br /&gt;
                                     player, function(err, count) {&lt;br /&gt;
                                         if (err) {&lt;br /&gt;
                                             console.log(&lt;br /&gt;
                                                 &amp;quot;Couldn&#039;t save player state&amp;quot;);&lt;br /&gt;
                                         }&lt;br /&gt;
                                     });&lt;br /&gt;
            roomsCollection.findOne(&lt;br /&gt;
                {name: roomName},&lt;br /&gt;
                function(err, room) {&lt;br /&gt;
                    if (err || !room) {&lt;br /&gt;
                        throw &amp;quot;Couldn&#039;t find room &amp;quot; + roomName;&lt;br /&gt;
                    }&lt;br /&gt;
                    res.render(&amp;quot;room.jade&amp;quot;, room); //renders an html page with room.jade template&lt;br /&gt;
                }&lt;br /&gt;
            );&lt;br /&gt;
        } else {&lt;br /&gt;
            res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return handler;&lt;br /&gt;
}&lt;br /&gt;
exports.getRooms = function() {&lt;br /&gt;
    return roomsCollection.find({name: &amp;quot;roomList&amp;quot;}); //finds all the rooms with the name in the roomlist&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===public/javascripts/home.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
$(function(){&lt;br /&gt;
	$(&amp;quot;#register&amp;quot;).on(&amp;quot;click&amp;quot;,function(){&lt;br /&gt;
		var $form = $(&amp;quot;form&amp;quot;);&lt;br /&gt;
		$form.attr(&amp;quot;action&amp;quot;,&amp;quot;/register&amp;quot;);&lt;br /&gt;
		$form.submit();&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/layout.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
doctype html&lt;br /&gt;
html&lt;br /&gt;
  head&lt;br /&gt;
    title= title&lt;br /&gt;
    script(src=&#039;/vendor/jquery/jquery.js&#039;)&lt;br /&gt;
    script(&#039;vendor/bootstrap/dist/js/bootstrap.js&#039;)&lt;br /&gt;
    link(rel=&#039;stylesheet&#039;, href=&#039;/vendor/bootstrap/dist/css/bootstrap.css&#039;)&lt;br /&gt;
    link(rel=&#039;stylesheet&#039;, href=&#039;/stylesheets/style.css&#039;)&lt;br /&gt;
    block header  &lt;br /&gt;
  body&lt;br /&gt;
    block content&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/index.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
extends layout //inherits formatting from layout.jade&lt;br /&gt;
&lt;br /&gt;
block header&lt;br /&gt;
  script(src=&#039;/javascripts/home.js&#039;) //applies javascript. Affects the register button&lt;br /&gt;
&lt;br /&gt;
block content&lt;br /&gt;
  h1= title&lt;br /&gt;
  - if(error)&lt;br /&gt;
    div.alert-error #{error}&lt;br /&gt;
  p Please log in&lt;br /&gt;
  div&lt;br /&gt;
    form(action=&amp;quot;/start&amp;quot;, method=&amp;quot;post&amp;quot;)&lt;br /&gt;
        div.control-group.input-append&lt;br /&gt;
            input(type=&amp;quot;text&amp;quot;, name=&amp;quot;playername&amp;quot;)&lt;br /&gt;
            label.add-on(for=&amp;quot;playername&amp;quot;) Player Name&lt;br /&gt;
        div.control-group.input-append&lt;br /&gt;
            input(type=&amp;quot;password&amp;quot;, name=&amp;quot;password&amp;quot;)&lt;br /&gt;
            label.add-on(for=&amp;quot;password&amp;quot;) Password&lt;br /&gt;
            &lt;br /&gt;
        button(type=&amp;quot;submit&amp;quot;) Start&lt;br /&gt;
        button#register(type=&amp;quot;button&amp;quot;) Register&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/room.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
extends layout&lt;br /&gt;
&lt;br /&gt;
block content&lt;br /&gt;
  h1= title&lt;br /&gt;
  p #{description}&lt;br /&gt;
  p Go to:&lt;br /&gt;
  ul&lt;br /&gt;
    each theExit in roomExits //exits are listed for every room&lt;br /&gt;
      li&lt;br /&gt;
        a(href= theExit) #{theExit}&lt;br /&gt;
  form(action=&amp;quot;/quit&amp;quot;, method=&amp;quot;post&amp;quot;)&lt;br /&gt;
     button(type=&amp;quot;submit&amp;quot;) Quit //creates a quit button on every room&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Midterm_Review&amp;diff=18830</id>
		<title>WebFund 2014W Midterm Review</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Midterm_Review&amp;diff=18830"/>
		<updated>2014-03-13T18:20:18Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on Feb. 12, 2014 is available:&lt;br /&gt;
* [http://www.screencast.com/t/9bmB5dTEoC small at Screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/nC3DlJrkoqt large at Screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Midterm_Review_-_20140212_150208_27.mp4 Original at CUOL]&lt;br /&gt;
&lt;br /&gt;
The midterm will be based on [http://homeostasis.scs.carleton.ca/~soma/webfund-2014w/midterm/small-adventure.zip small-adventure], a version of &amp;lt;tt&amp;gt;adventure-demo&amp;lt;/tt&amp;gt; that has been simplified by removing the use of cryptography (https and bcrypt) along with a few other minor tweaks to reduce the size of the source code.&lt;br /&gt;
&lt;br /&gt;
No new tutorial this week; however, two TAs/instructors will be in the lab on Thursday 4-5:30 and Friday 8:30-10 to answer last minute questions.&lt;br /&gt;
&lt;br /&gt;
==Midterm Review Notes==&lt;br /&gt;
* Most of the notes are written inline in the source code to make the line it refers to more clear:&lt;br /&gt;
&lt;br /&gt;
What is the state of the system after app,js runs?&lt;br /&gt;
* We don&#039;t know what it is because you only know when the call back is run.&lt;br /&gt;
* app.get/app.post are only run ONCE! It tells the web server what to do when http GET and POST requests are received at specific urls. Note that these are only run ONCE, before the web server starts listening for incoming connections.&lt;br /&gt;
&lt;br /&gt;
Asynchronous vs Synchronous:&lt;br /&gt;
* The analogy that Anil give was that synchronous is like a 5 year old child waiting for cookies to be baked. He asks &amp;quot;is it ready yet?&amp;quot; every 5 minutes. He&#039;s not doing anything else. Asynchronous is like a 8 year old child, who does something else (e.g. read a book) while he waits for the cookies to be baked&lt;br /&gt;
&lt;br /&gt;
==Source for small-adventure==&lt;br /&gt;
&lt;br /&gt;
===app.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var express = require(&#039;express&#039;); //requires the express module&lt;br /&gt;
var routes = require(&#039;./routes&#039;); //same as (&#039;/routes/index.js&#039;). The require() method returns the exports object&lt;br /&gt;
var path = require(&#039;path&#039;); //imports the path module, or path.join will not be defined&lt;br /&gt;
var http = require(&#039;http&#039;); //requires the http module&lt;br /&gt;
var MongoStore = require(&#039;connect-mongo&#039;)(express);&lt;br /&gt;
&lt;br /&gt;
var app = express(); //creates an express object instance and assigns the app variable to it.&lt;br /&gt;
&lt;br /&gt;
app.set(&#039;port&#039;, process.env.PORT || 3000); //listens on PORT environment variable OR port 3000 if not defined&lt;br /&gt;
app.set(&#039;views&#039;, path.join(__dirname, &#039;views&#039;)); //sets the location for application views&lt;br /&gt;
app.set(&#039;view engine&#039;, &#039;jade&#039;); //sets the view engine, Jade&lt;br /&gt;
app.use(express.favicon()); //can specify where you want favicon to be found in the parameters. e.g (_dirname + &#039;public/favicon.ico&#039;)&lt;br /&gt;
app.use(express.logger(&#039;dev&#039;)); //logging requests using predefined log format &#039;dev&#039;. This will generate a detail log.&lt;br /&gt;
app.use(express.urlencoded()); //The body of HTTP post requests. Parses the incoming request body, converting it into request object properties&lt;br /&gt;
&lt;br /&gt;
app.use(express.cookieParser()); &lt;br /&gt;
app.use(express.session({&lt;br /&gt;
    cookie: {maxAge: 60000 * 20} // 20 minutes&lt;br /&gt;
    , secret: &amp;quot;Shh... I&#039;m a secret&amp;quot; //This is the secret that prevents attackers from creating their own fake session identifiers&lt;br /&gt;
    , store: new MongoStore({db: &amp;quot;adventure-demo&amp;quot;})&lt;br /&gt;
}));&lt;br /&gt;
&lt;br /&gt;
app.use(app.router);&lt;br /&gt;
app.use(express.static(path.join(__dirname, &#039;public&#039;))); //serves static files from the root path. The CSS files and fonts are all stored in the public directory, which is made publicly accessible by this line.&lt;br /&gt;
&lt;br /&gt;
if (&#039;development&#039; == app.get(&#039;env&#039;)) {&lt;br /&gt;
  app.use(express.errorHandler());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//The purpose of these lines is to setup routes. It tells the web server what to do when http GET and POST requests are received at specific urls. Note that these are only run ONCE, before the web server starts listening for incoming connections.&lt;br /&gt;
app.get(&#039;/&#039;, routes.redirectLoggedIn, routes.index); //requests the home page (https://localhost:3000)&lt;br /&gt;
app.post(&amp;quot;/register&amp;quot;, routes.register);&lt;br /&gt;
app.post(&amp;quot;/start&amp;quot;, routes.start);&lt;br /&gt;
app.post(&amp;quot;/quit&amp;quot;, routes.quit);&lt;br /&gt;
&lt;br /&gt;
var createRooms = function() {&lt;br /&gt;
    var i, theRoom;&lt;br /&gt;
&lt;br /&gt;
    routes.getRooms().toArray( //a call to getRooms and a call toArray, which is a method of the collections object. This runs the query and puts the results into an array&lt;br /&gt;
        function(err, docs) {&lt;br /&gt;
            if (err) {&lt;br /&gt;
                throw &amp;quot;Couldn&#039;t find active room list&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            var activeRooms = docs[0].activeRooms;&lt;br /&gt;
&lt;br /&gt;
            activeRooms.forEach(function(roomName) { //roomName is our index variable, we get the room element. ActiveRooms is an array of roomName.&lt;br /&gt;
                console.log(&#039;Creating room: &#039; + roomName);&lt;br /&gt;
                app.get(&#039;/&#039; + roomName,&lt;br /&gt;
                        routes.makeRoomHandler(roomName));&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
routes.connectToDBs(createRooms);&lt;br /&gt;
&lt;br /&gt;
http.createServer(app).listen(app.get(&#039;port&#039;), function(){&lt;br /&gt;
  console.log(&#039;Express server listening on port &#039; + app.get(&#039;port&#039;) +&lt;br /&gt;
              &#039; in &#039; + app.get(&#039;env&#039;) + &#039; mode.&#039;);&lt;br /&gt;
});&lt;br /&gt;
//1) createServer(): a method of http that creates and returns a server object&lt;br /&gt;
//2) listen(): a method at the returned server object that starts the web server listening on a given port&lt;br /&gt;
//3) app.get(): returns the port to listen on&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===routes/index.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var mc = require(&#039;mongodb&#039;).MongoClient;&lt;br /&gt;
var playersCollection, roomsCollection;&lt;br /&gt;
exports.connectToDBs = function(callback) {&lt;br /&gt;
    mc.connect(&#039;mongodb://localhost/adventure-demo&#039;, function(err, db) {&lt;br /&gt;
        if (err) {&lt;br /&gt;
            throw err;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        playersCollection = db.collection(&#039;players&#039;);&lt;br /&gt;
        roomsCollection = db.collection(&#039;rooms&#039;);&lt;br /&gt;
&lt;br /&gt;
        callback(); //is createRooms. We do the callback after the database is established because we need to setup the database first.&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//assigned to the properties of the exports object&lt;br /&gt;
exports.index = function(req, res){&lt;br /&gt;
    res.render(&#039;index&#039;, { title: &#039;COMP 2406 Small Adventure Demo&#039;,&lt;br /&gt;
                          error: req.query.error });&lt;br /&gt;
}&lt;br /&gt;
exports.redirectLoggedIn = function(req, res, next) {&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot; + req.session.player.room);&lt;br /&gt;
    } else {&lt;br /&gt;
        next();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
exports.redirectNotLoggedIn = function(req, res, next) {&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
        next();&lt;br /&gt;
    } else {&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
exports.register = function(req, res) {&lt;br /&gt;
    var playername = req.body.playername; //req.body retrieves the value for the playername attribute&lt;br /&gt;
    var password = req.body.password;&lt;br /&gt;
&lt;br /&gt;
    var addPlayer = function(err, players) {&lt;br /&gt;
        if(players.length!=0){&lt;br /&gt;
            res.redirect(&amp;quot;/?error=player already exists&amp;quot;);      &lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        var newPlayer = {&lt;br /&gt;
            playername: playername,&lt;br /&gt;
            password: password,&lt;br /&gt;
            room: &amp;quot;bridge&amp;quot;&lt;br /&gt;
        };&lt;br /&gt;
                &lt;br /&gt;
        playersCollection.insert(newPlayer, function(err, newPlayers){&lt;br /&gt;
            if (err) {&lt;br /&gt;
                throw err;&lt;br /&gt;
            } else {&lt;br /&gt;
                res.send(&#039;Successfully registered &#039; + newPlayers[0].playername);&lt;br /&gt;
            }&lt;br /&gt;
        });    &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    playersCollection.find({playername: playername}).toArray(addPlayer);&lt;br /&gt;
}&lt;br /&gt;
exports.start = function(req, res){&lt;br /&gt;
    var playername = req.body.playername;&lt;br /&gt;
    var password = req.body.password;&lt;br /&gt;
&lt;br /&gt;
    playersCollection.findOne({playername: playername}, function(err, player) {&lt;br /&gt;
        if (err || !player){&lt;br /&gt;
            req.session.destroy(function(err) {&lt;br /&gt;
                res.redirect(&amp;quot;/?error=invalid playername or password&amp;quot;); &lt;br /&gt;
            });&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (password === player.password) {&lt;br /&gt;
            req.session.player = player;&lt;br /&gt;
            delete req.session.player._id;&lt;br /&gt;
            res.redirect(&amp;quot;/&amp;quot; + player.room);&lt;br /&gt;
        } else {&lt;br /&gt;
            req.session.destroy(function(err) {&lt;br /&gt;
                res.redirect(&amp;quot;/?error=invalid playername or password&amp;quot;);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
exports.quit = function(req, res){&lt;br /&gt;
    req.session.destroy(function(err){&lt;br /&gt;
        if(err){&lt;br /&gt;
            console.log(&amp;quot;Error: %s&amp;quot;, err);&lt;br /&gt;
        }&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
    }); &lt;br /&gt;
}&lt;br /&gt;
exports.makeRoomHandler = function(roomName) {&lt;br /&gt;
    var handler = function(req, res) { //without &#039;var&#039; handler becomes a global variable&lt;br /&gt;
        if (req.session.player) {&lt;br /&gt;
            var player = req.session.player;&lt;br /&gt;
            player.room = roomName;&lt;br /&gt;
            playersCollection.update({&amp;quot;playername&amp;quot;: player.playername},&lt;br /&gt;
                                     player, function(err, count) {&lt;br /&gt;
                                         if (err) {&lt;br /&gt;
                                             console.log(&lt;br /&gt;
                                                 &amp;quot;Couldn&#039;t save player state&amp;quot;);&lt;br /&gt;
                                         }&lt;br /&gt;
                                     });&lt;br /&gt;
            roomsCollection.findOne(&lt;br /&gt;
                {name: roomName},&lt;br /&gt;
                function(err, room) {&lt;br /&gt;
                    if (err || !room) {&lt;br /&gt;
                        throw &amp;quot;Couldn&#039;t find room &amp;quot; + roomName;&lt;br /&gt;
                    }&lt;br /&gt;
                    res.render(&amp;quot;room.jade&amp;quot;, room); //renders an html page with room.jade template&lt;br /&gt;
                }&lt;br /&gt;
            );&lt;br /&gt;
        } else {&lt;br /&gt;
            res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return handler;&lt;br /&gt;
}&lt;br /&gt;
exports.getRooms = function() {&lt;br /&gt;
    return roomsCollection.find({name: &amp;quot;roomList&amp;quot;}); //finds all the rooms with the name in the roomlist&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===public/javascripts/home.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
$(function(){&lt;br /&gt;
	$(&amp;quot;#register&amp;quot;).on(&amp;quot;click&amp;quot;,function(){&lt;br /&gt;
		var $form = $(&amp;quot;form&amp;quot;);&lt;br /&gt;
		$form.attr(&amp;quot;action&amp;quot;,&amp;quot;/register&amp;quot;);&lt;br /&gt;
		$form.submit();&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/layout.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
doctype html&lt;br /&gt;
html&lt;br /&gt;
  head&lt;br /&gt;
    title= title&lt;br /&gt;
    script(src=&#039;/vendor/jquery/jquery.js&#039;)&lt;br /&gt;
    script(&#039;vendor/bootstrap/dist/js/bootstrap.js&#039;)&lt;br /&gt;
    link(rel=&#039;stylesheet&#039;, href=&#039;/vendor/bootstrap/dist/css/bootstrap.css&#039;)&lt;br /&gt;
    link(rel=&#039;stylesheet&#039;, href=&#039;/stylesheets/style.css&#039;)&lt;br /&gt;
    block header  &lt;br /&gt;
  body&lt;br /&gt;
    block content&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/index.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
extends layout //inherits formatting from layout.jade&lt;br /&gt;
&lt;br /&gt;
block header&lt;br /&gt;
  script(src=&#039;/javascripts/home.js&#039;) //applies javascript. Affects the register button&lt;br /&gt;
&lt;br /&gt;
block content&lt;br /&gt;
  h1= title&lt;br /&gt;
  - if(error)&lt;br /&gt;
    div.alert-error #{error}&lt;br /&gt;
  p Please log in&lt;br /&gt;
  div&lt;br /&gt;
    form(action=&amp;quot;/start&amp;quot;, method=&amp;quot;post&amp;quot;)&lt;br /&gt;
        div.control-group.input-append&lt;br /&gt;
            input(type=&amp;quot;text&amp;quot;, name=&amp;quot;playername&amp;quot;)&lt;br /&gt;
            label.add-on(for=&amp;quot;playername&amp;quot;) Player Name&lt;br /&gt;
        div.control-group.input-append&lt;br /&gt;
            input(type=&amp;quot;password&amp;quot;, name=&amp;quot;password&amp;quot;)&lt;br /&gt;
            label.add-on(for=&amp;quot;password&amp;quot;) Password&lt;br /&gt;
            &lt;br /&gt;
        button(type=&amp;quot;submit&amp;quot;) Start&lt;br /&gt;
        button#register(type=&amp;quot;button&amp;quot;) Register&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/room.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
extends layout&lt;br /&gt;
&lt;br /&gt;
block content&lt;br /&gt;
  h1= title&lt;br /&gt;
  p #{description}&lt;br /&gt;
  p Go to:&lt;br /&gt;
  ul&lt;br /&gt;
    each theExit in roomExits //exits are listed for every room&lt;br /&gt;
      li&lt;br /&gt;
        a(href= theExit) #{theExit}&lt;br /&gt;
  form(action=&amp;quot;/quit&amp;quot;, method=&amp;quot;post&amp;quot;)&lt;br /&gt;
     button(type=&amp;quot;submit&amp;quot;) Quit //creates a quit button on every room&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Midterm_Review&amp;diff=18829</id>
		<title>WebFund 2014W Midterm Review</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Midterm_Review&amp;diff=18829"/>
		<updated>2014-03-13T18:19:48Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on Feb. 12, 2014 is available:&lt;br /&gt;
* [http://www.screencast.com/t/9bmB5dTEoC small at Screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/nC3DlJrkoqt large at Screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Midterm_Review_-_20140212_150208_27.mp4 Original at CUOL]&lt;br /&gt;
&lt;br /&gt;
The midterm will be based on [http://homeostasis.scs.carleton.ca/~soma/webfund-2014w/midterm/small-adventure.zip small-adventure], a version of &amp;lt;tt&amp;gt;adventure-demo&amp;lt;/tt&amp;gt; that has been simplified by removing the use of cryptography (https and bcrypt) along with a few other minor tweaks to reduce the size of the source code.&lt;br /&gt;
&lt;br /&gt;
No new tutorial this week; however, two TAs/instructors will be in the lab on Thursday 4-5:30 and Friday 8:30-10 to answer last minute questions.&lt;br /&gt;
&lt;br /&gt;
==Midterm Review Notes==&lt;br /&gt;
Note that most of the notes are written inline in the source code to make the line it refers to more clear:&lt;br /&gt;
&lt;br /&gt;
What is the state of the system after app,js runs?&lt;br /&gt;
* We don&#039;t know what it is because you only know when the call back is run.&lt;br /&gt;
* app.get/app.post are only run ONCE! It tells the web server what to do when http GET and POST requests are received at specific urls. Note that these are only run ONCE, before the web server starts listening for incoming connections.&lt;br /&gt;
&lt;br /&gt;
Asynchronous vs Synchronous:&lt;br /&gt;
* The analogy that Anil give was that synchronous is like a 5 year old child waiting for cookies to be baked. He asks &amp;quot;is it ready yet?&amp;quot; every 5 minutes. He&#039;s not doing anything else. Asynchronous is like a 8 year old child, who does something else (e.g. read a book) while he waits for the cookies to be baked&lt;br /&gt;
&lt;br /&gt;
==Source for small-adventure==&lt;br /&gt;
&lt;br /&gt;
===app.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var express = require(&#039;express&#039;); //requires the express module&lt;br /&gt;
var routes = require(&#039;./routes&#039;); //same as (&#039;/routes/index.js&#039;). The require() method returns the exports object&lt;br /&gt;
var path = require(&#039;path&#039;); //imports the path module, or path.join will not be defined&lt;br /&gt;
var http = require(&#039;http&#039;); //requires the http module&lt;br /&gt;
var MongoStore = require(&#039;connect-mongo&#039;)(express);&lt;br /&gt;
&lt;br /&gt;
var app = express(); //creates an express object instance and assigns the app variable to it.&lt;br /&gt;
&lt;br /&gt;
app.set(&#039;port&#039;, process.env.PORT || 3000); //listens on PORT environment variable OR port 3000 if not defined&lt;br /&gt;
app.set(&#039;views&#039;, path.join(__dirname, &#039;views&#039;)); //sets the location for application views&lt;br /&gt;
app.set(&#039;view engine&#039;, &#039;jade&#039;); //sets the view engine, Jade&lt;br /&gt;
app.use(express.favicon()); //can specify where you want favicon to be found in the parameters. e.g (_dirname + &#039;public/favicon.ico&#039;)&lt;br /&gt;
app.use(express.logger(&#039;dev&#039;)); //logging requests using predefined log format &#039;dev&#039;. This will generate a detail log.&lt;br /&gt;
app.use(express.urlencoded()); //The body of HTTP post requests. Parses the incoming request body, converting it into request object properties&lt;br /&gt;
&lt;br /&gt;
app.use(express.cookieParser()); &lt;br /&gt;
app.use(express.session({&lt;br /&gt;
    cookie: {maxAge: 60000 * 20} // 20 minutes&lt;br /&gt;
    , secret: &amp;quot;Shh... I&#039;m a secret&amp;quot; //This is the secret that prevents attackers from creating their own fake session identifiers&lt;br /&gt;
    , store: new MongoStore({db: &amp;quot;adventure-demo&amp;quot;})&lt;br /&gt;
}));&lt;br /&gt;
&lt;br /&gt;
app.use(app.router);&lt;br /&gt;
app.use(express.static(path.join(__dirname, &#039;public&#039;))); //serves static files from the root path. The CSS files and fonts are all stored in the public directory, which is made publicly accessible by this line.&lt;br /&gt;
&lt;br /&gt;
if (&#039;development&#039; == app.get(&#039;env&#039;)) {&lt;br /&gt;
  app.use(express.errorHandler());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//The purpose of these lines is to setup routes. It tells the web server what to do when http GET and POST requests are received at specific urls. Note that these are only run ONCE, before the web server starts listening for incoming connections.&lt;br /&gt;
app.get(&#039;/&#039;, routes.redirectLoggedIn, routes.index); //requests the home page (https://localhost:3000)&lt;br /&gt;
app.post(&amp;quot;/register&amp;quot;, routes.register);&lt;br /&gt;
app.post(&amp;quot;/start&amp;quot;, routes.start);&lt;br /&gt;
app.post(&amp;quot;/quit&amp;quot;, routes.quit);&lt;br /&gt;
&lt;br /&gt;
var createRooms = function() {&lt;br /&gt;
    var i, theRoom;&lt;br /&gt;
&lt;br /&gt;
    routes.getRooms().toArray( //a call to getRooms and a call toArray, which is a method of the collections object. This runs the query and puts the results into an array&lt;br /&gt;
        function(err, docs) {&lt;br /&gt;
            if (err) {&lt;br /&gt;
                throw &amp;quot;Couldn&#039;t find active room list&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            var activeRooms = docs[0].activeRooms;&lt;br /&gt;
&lt;br /&gt;
            activeRooms.forEach(function(roomName) { //roomName is our index variable, we get the room element. ActiveRooms is an array of roomName.&lt;br /&gt;
                console.log(&#039;Creating room: &#039; + roomName);&lt;br /&gt;
                app.get(&#039;/&#039; + roomName,&lt;br /&gt;
                        routes.makeRoomHandler(roomName));&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
routes.connectToDBs(createRooms);&lt;br /&gt;
&lt;br /&gt;
http.createServer(app).listen(app.get(&#039;port&#039;), function(){&lt;br /&gt;
  console.log(&#039;Express server listening on port &#039; + app.get(&#039;port&#039;) +&lt;br /&gt;
              &#039; in &#039; + app.get(&#039;env&#039;) + &#039; mode.&#039;);&lt;br /&gt;
});&lt;br /&gt;
//1) createServer(): a method of http that creates and returns a server object&lt;br /&gt;
//2) listen(): a method at the returned server object that starts the web server listening on a given port&lt;br /&gt;
//3) app.get(): returns the port to listen on&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===routes/index.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var mc = require(&#039;mongodb&#039;).MongoClient;&lt;br /&gt;
var playersCollection, roomsCollection;&lt;br /&gt;
exports.connectToDBs = function(callback) {&lt;br /&gt;
    mc.connect(&#039;mongodb://localhost/adventure-demo&#039;, function(err, db) {&lt;br /&gt;
        if (err) {&lt;br /&gt;
            throw err;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        playersCollection = db.collection(&#039;players&#039;);&lt;br /&gt;
        roomsCollection = db.collection(&#039;rooms&#039;);&lt;br /&gt;
&lt;br /&gt;
        callback(); //is createRooms. We do the callback after the database is established because we need to setup the database first.&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//assigned to the properties of the exports object&lt;br /&gt;
exports.index = function(req, res){&lt;br /&gt;
    res.render(&#039;index&#039;, { title: &#039;COMP 2406 Small Adventure Demo&#039;,&lt;br /&gt;
                          error: req.query.error });&lt;br /&gt;
}&lt;br /&gt;
exports.redirectLoggedIn = function(req, res, next) {&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot; + req.session.player.room);&lt;br /&gt;
    } else {&lt;br /&gt;
        next();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
exports.redirectNotLoggedIn = function(req, res, next) {&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
        next();&lt;br /&gt;
    } else {&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
exports.register = function(req, res) {&lt;br /&gt;
    var playername = req.body.playername; //req.body retrieves the value for the playername attribute&lt;br /&gt;
    var password = req.body.password;&lt;br /&gt;
&lt;br /&gt;
    var addPlayer = function(err, players) {&lt;br /&gt;
        if(players.length!=0){&lt;br /&gt;
            res.redirect(&amp;quot;/?error=player already exists&amp;quot;);      &lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        var newPlayer = {&lt;br /&gt;
            playername: playername,&lt;br /&gt;
            password: password,&lt;br /&gt;
            room: &amp;quot;bridge&amp;quot;&lt;br /&gt;
        };&lt;br /&gt;
                &lt;br /&gt;
        playersCollection.insert(newPlayer, function(err, newPlayers){&lt;br /&gt;
            if (err) {&lt;br /&gt;
                throw err;&lt;br /&gt;
            } else {&lt;br /&gt;
                res.send(&#039;Successfully registered &#039; + newPlayers[0].playername);&lt;br /&gt;
            }&lt;br /&gt;
        });    &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    playersCollection.find({playername: playername}).toArray(addPlayer);&lt;br /&gt;
}&lt;br /&gt;
exports.start = function(req, res){&lt;br /&gt;
    var playername = req.body.playername;&lt;br /&gt;
    var password = req.body.password;&lt;br /&gt;
&lt;br /&gt;
    playersCollection.findOne({playername: playername}, function(err, player) {&lt;br /&gt;
        if (err || !player){&lt;br /&gt;
            req.session.destroy(function(err) {&lt;br /&gt;
                res.redirect(&amp;quot;/?error=invalid playername or password&amp;quot;); &lt;br /&gt;
            });&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (password === player.password) {&lt;br /&gt;
            req.session.player = player;&lt;br /&gt;
            delete req.session.player._id;&lt;br /&gt;
            res.redirect(&amp;quot;/&amp;quot; + player.room);&lt;br /&gt;
        } else {&lt;br /&gt;
            req.session.destroy(function(err) {&lt;br /&gt;
                res.redirect(&amp;quot;/?error=invalid playername or password&amp;quot;);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
exports.quit = function(req, res){&lt;br /&gt;
    req.session.destroy(function(err){&lt;br /&gt;
        if(err){&lt;br /&gt;
            console.log(&amp;quot;Error: %s&amp;quot;, err);&lt;br /&gt;
        }&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
    }); &lt;br /&gt;
}&lt;br /&gt;
exports.makeRoomHandler = function(roomName) {&lt;br /&gt;
    var handler = function(req, res) { //without &#039;var&#039; handler becomes a global variable&lt;br /&gt;
        if (req.session.player) {&lt;br /&gt;
            var player = req.session.player;&lt;br /&gt;
            player.room = roomName;&lt;br /&gt;
            playersCollection.update({&amp;quot;playername&amp;quot;: player.playername},&lt;br /&gt;
                                     player, function(err, count) {&lt;br /&gt;
                                         if (err) {&lt;br /&gt;
                                             console.log(&lt;br /&gt;
                                                 &amp;quot;Couldn&#039;t save player state&amp;quot;);&lt;br /&gt;
                                         }&lt;br /&gt;
                                     });&lt;br /&gt;
            roomsCollection.findOne(&lt;br /&gt;
                {name: roomName},&lt;br /&gt;
                function(err, room) {&lt;br /&gt;
                    if (err || !room) {&lt;br /&gt;
                        throw &amp;quot;Couldn&#039;t find room &amp;quot; + roomName;&lt;br /&gt;
                    }&lt;br /&gt;
                    res.render(&amp;quot;room.jade&amp;quot;, room); //renders an html page with room.jade template&lt;br /&gt;
                }&lt;br /&gt;
            );&lt;br /&gt;
        } else {&lt;br /&gt;
            res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return handler;&lt;br /&gt;
}&lt;br /&gt;
exports.getRooms = function() {&lt;br /&gt;
    return roomsCollection.find({name: &amp;quot;roomList&amp;quot;}); //finds all the rooms with the name in the roomlist&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===public/javascripts/home.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
$(function(){&lt;br /&gt;
	$(&amp;quot;#register&amp;quot;).on(&amp;quot;click&amp;quot;,function(){&lt;br /&gt;
		var $form = $(&amp;quot;form&amp;quot;);&lt;br /&gt;
		$form.attr(&amp;quot;action&amp;quot;,&amp;quot;/register&amp;quot;);&lt;br /&gt;
		$form.submit();&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/layout.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
doctype html&lt;br /&gt;
html&lt;br /&gt;
  head&lt;br /&gt;
    title= title&lt;br /&gt;
    script(src=&#039;/vendor/jquery/jquery.js&#039;)&lt;br /&gt;
    script(&#039;vendor/bootstrap/dist/js/bootstrap.js&#039;)&lt;br /&gt;
    link(rel=&#039;stylesheet&#039;, href=&#039;/vendor/bootstrap/dist/css/bootstrap.css&#039;)&lt;br /&gt;
    link(rel=&#039;stylesheet&#039;, href=&#039;/stylesheets/style.css&#039;)&lt;br /&gt;
    block header  &lt;br /&gt;
  body&lt;br /&gt;
    block content&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/index.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
extends layout //inherits formatting from layout.jade&lt;br /&gt;
&lt;br /&gt;
block header&lt;br /&gt;
  script(src=&#039;/javascripts/home.js&#039;) //applies javascript. Affects the register button&lt;br /&gt;
&lt;br /&gt;
block content&lt;br /&gt;
  h1= title&lt;br /&gt;
  - if(error)&lt;br /&gt;
    div.alert-error #{error}&lt;br /&gt;
  p Please log in&lt;br /&gt;
  div&lt;br /&gt;
    form(action=&amp;quot;/start&amp;quot;, method=&amp;quot;post&amp;quot;)&lt;br /&gt;
        div.control-group.input-append&lt;br /&gt;
            input(type=&amp;quot;text&amp;quot;, name=&amp;quot;playername&amp;quot;)&lt;br /&gt;
            label.add-on(for=&amp;quot;playername&amp;quot;) Player Name&lt;br /&gt;
        div.control-group.input-append&lt;br /&gt;
            input(type=&amp;quot;password&amp;quot;, name=&amp;quot;password&amp;quot;)&lt;br /&gt;
            label.add-on(for=&amp;quot;password&amp;quot;) Password&lt;br /&gt;
            &lt;br /&gt;
        button(type=&amp;quot;submit&amp;quot;) Start&lt;br /&gt;
        button#register(type=&amp;quot;button&amp;quot;) Register&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/room.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
extends layout&lt;br /&gt;
&lt;br /&gt;
block content&lt;br /&gt;
  h1= title&lt;br /&gt;
  p #{description}&lt;br /&gt;
  p Go to:&lt;br /&gt;
  ul&lt;br /&gt;
    each theExit in roomExits //exits are listed for every room&lt;br /&gt;
      li&lt;br /&gt;
        a(href= theExit) #{theExit}&lt;br /&gt;
  form(action=&amp;quot;/quit&amp;quot;, method=&amp;quot;post&amp;quot;)&lt;br /&gt;
     button(type=&amp;quot;submit&amp;quot;) Quit //creates a quit button on every room&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Midterm_Review&amp;diff=18828</id>
		<title>WebFund 2014W Midterm Review</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Midterm_Review&amp;diff=18828"/>
		<updated>2014-03-13T18:14:35Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on Feb. 12, 2014 is available:&lt;br /&gt;
* [http://www.screencast.com/t/9bmB5dTEoC small at Screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/nC3DlJrkoqt large at Screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Midterm_Review_-_20140212_150208_27.mp4 Original at CUOL]&lt;br /&gt;
&lt;br /&gt;
The midterm will be based on [http://homeostasis.scs.carleton.ca/~soma/webfund-2014w/midterm/small-adventure.zip small-adventure], a version of &amp;lt;tt&amp;gt;adventure-demo&amp;lt;/tt&amp;gt; that has been simplified by removing the use of cryptography (https and bcrypt) along with a few other minor tweaks to reduce the size of the source code.&lt;br /&gt;
&lt;br /&gt;
No new tutorial this week; however, two TAs/instructors will be in the lab on Thursday 4-5:30 and Friday 8:30-10 to answer last minute questions.&lt;br /&gt;
&lt;br /&gt;
==Midterm Review Notes==&lt;br /&gt;
Note that most of the notes are written inline in the source code to make the line it refers to more clear:&lt;br /&gt;
&lt;br /&gt;
What is the state of the system after app,js runs?&lt;br /&gt;
* We don&#039;t know what it is because you only know when the call back is run.&lt;br /&gt;
* app.get/app.post are only run ONCE! It tells the web server what to do when http GET and POST requests are received at specific urls. Note that these are only run ONCE, before the web server starts listening for incoming connections.&lt;br /&gt;
&lt;br /&gt;
Asynchronous vs Synchronous:&lt;br /&gt;
* The analogy that Anil give was that synchronous is like a 5 year old child waiting for cookies to be baked. He asks &amp;quot;is it ready yet?&amp;quot; every 5 minutes. He&#039;s not doing anything else. Asynchronous is like a 8 year old child, who does something else (e.g. read a book) while he waits for the cookies to be baked&lt;br /&gt;
&lt;br /&gt;
==Source for small-adventure==&lt;br /&gt;
&lt;br /&gt;
===app.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var express = require(&#039;express&#039;); //requires the express module&lt;br /&gt;
var routes = require(&#039;./routes&#039;); //same as (&#039;/routes/index.js&#039;). The require() method returns the exports object&lt;br /&gt;
var path = require(&#039;path&#039;); //imports the path module, or path.join will not be defined&lt;br /&gt;
var http = require(&#039;http&#039;); //requires the http module&lt;br /&gt;
var MongoStore = require(&#039;connect-mongo&#039;)(express);&lt;br /&gt;
&lt;br /&gt;
var app = express(); //creates an express object instance and assigns the app variable to it.&lt;br /&gt;
&lt;br /&gt;
app.set(&#039;port&#039;, process.env.PORT || 3000); //listens on PORT environment variable OR port 3000 if not defined&lt;br /&gt;
app.set(&#039;views&#039;, path.join(__dirname, &#039;views&#039;)); //sets the location for application views&lt;br /&gt;
app.set(&#039;view engine&#039;, &#039;jade&#039;); //sets the view engine, Jade&lt;br /&gt;
app.use(express.favicon()); //can specify where you want favicon to be found in the parameters. e.g (_dirname + &#039;public/favicon.ico&#039;)&lt;br /&gt;
app.use(express.logger(&#039;dev&#039;)); //logging requests using predefined log format &#039;dev&#039;. This will generate a detail log.&lt;br /&gt;
app.use(express.urlencoded()); //The body of HTTP post requests. Parses the incoming request body, converting it into request object properties&lt;br /&gt;
&lt;br /&gt;
app.use(express.cookieParser()); &lt;br /&gt;
app.use(express.session({&lt;br /&gt;
    cookie: {maxAge: 60000 * 20} // 20 minutes&lt;br /&gt;
    , secret: &amp;quot;Shh... I&#039;m a secret&amp;quot; //This is the secret that prevents attackers from creating their own fake session identifiers&lt;br /&gt;
    , store: new MongoStore({db: &amp;quot;adventure-demo&amp;quot;})&lt;br /&gt;
}));&lt;br /&gt;
&lt;br /&gt;
app.use(app.router);&lt;br /&gt;
app.use(express.static(path.join(__dirname, &#039;public&#039;))); //serves static files from the root path. The CSS files and fonts are all stored in the public directory, which is made publicly accessible by this line.&lt;br /&gt;
&lt;br /&gt;
if (&#039;development&#039; == app.get(&#039;env&#039;)) {&lt;br /&gt;
  app.use(express.errorHandler());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//The purpose of these lines is to setup routes. It tells the web server what to do when http GET and POST requests are received at specific urls. Note that these are only run ONCE, before the web server starts listening for incoming connections.&lt;br /&gt;
app.get(&#039;/&#039;, routes.redirectLoggedIn, routes.index); //requests the home page (https://localhost:3000)&lt;br /&gt;
app.post(&amp;quot;/register&amp;quot;, routes.register);&lt;br /&gt;
app.post(&amp;quot;/start&amp;quot;, routes.start);&lt;br /&gt;
app.post(&amp;quot;/quit&amp;quot;, routes.quit);&lt;br /&gt;
&lt;br /&gt;
var createRooms = function() {&lt;br /&gt;
    var i, theRoom;&lt;br /&gt;
&lt;br /&gt;
    routes.getRooms().toArray( //a call to getRooms and a call toArray, which is a method of the collections object. This runs the query and puts the results into an array&lt;br /&gt;
        function(err, docs) {&lt;br /&gt;
            if (err) {&lt;br /&gt;
                throw &amp;quot;Couldn&#039;t find active room list&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            var activeRooms = docs[0].activeRooms;&lt;br /&gt;
&lt;br /&gt;
            activeRooms.forEach(function(roomName) { //roomName is our index variable, we get the room element. ActiveRooms is an array of roomName.&lt;br /&gt;
                console.log(&#039;Creating room: &#039; + roomName);&lt;br /&gt;
                app.get(&#039;/&#039; + roomName,&lt;br /&gt;
                        routes.makeRoomHandler(roomName));&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
routes.connectToDBs(createRooms);&lt;br /&gt;
&lt;br /&gt;
http.createServer(app).listen(app.get(&#039;port&#039;), function(){&lt;br /&gt;
  console.log(&#039;Express server listening on port &#039; + app.get(&#039;port&#039;) +&lt;br /&gt;
              &#039; in &#039; + app.get(&#039;env&#039;) + &#039; mode.&#039;);&lt;br /&gt;
});&lt;br /&gt;
//1) createServer(): a method of http that creates and returns a server object&lt;br /&gt;
//2) listen(): a method at the returned server object that starts the web server listening on a given port&lt;br /&gt;
//3) app.get(): returns the port to listen on&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===routes/index.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var mc = require(&#039;mongodb&#039;).MongoClient;&lt;br /&gt;
var playersCollection, roomsCollection;&lt;br /&gt;
exports.connectToDBs = function(callback) {&lt;br /&gt;
    mc.connect(&#039;mongodb://localhost/adventure-demo&#039;, function(err, db) {&lt;br /&gt;
        if (err) {&lt;br /&gt;
            throw err;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        playersCollection = db.collection(&#039;players&#039;);&lt;br /&gt;
        roomsCollection = db.collection(&#039;rooms&#039;);&lt;br /&gt;
&lt;br /&gt;
        callback(); //is createRooms. We do the callback after the database is established because we need to setup the database first.&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//assigned to the properties of the exports object&lt;br /&gt;
exports.index = function(req, res){&lt;br /&gt;
    res.render(&#039;index&#039;, { title: &#039;COMP 2406 Small Adventure Demo&#039;,&lt;br /&gt;
                          error: req.query.error });&lt;br /&gt;
}&lt;br /&gt;
exports.redirectLoggedIn = function(req, res, next) {&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot; + req.session.player.room);&lt;br /&gt;
    } else {&lt;br /&gt;
        next();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
exports.redirectNotLoggedIn = function(req, res, next) {&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
        next();&lt;br /&gt;
    } else {&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
exports.register = function(req, res) {&lt;br /&gt;
    var playername = req.body.playername; //req.body retrieves the value for the playername attribute&lt;br /&gt;
    var password = req.body.password;&lt;br /&gt;
&lt;br /&gt;
    var addPlayer = function(err, players) {&lt;br /&gt;
        if(players.length!=0){&lt;br /&gt;
            res.redirect(&amp;quot;/?error=player already exists&amp;quot;);      &lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        var newPlayer = {&lt;br /&gt;
            playername: playername,&lt;br /&gt;
            password: password,&lt;br /&gt;
            room: &amp;quot;bridge&amp;quot;&lt;br /&gt;
        };&lt;br /&gt;
                &lt;br /&gt;
        playersCollection.insert(newPlayer, function(err, newPlayers){&lt;br /&gt;
            if (err) {&lt;br /&gt;
                throw err;&lt;br /&gt;
            } else {&lt;br /&gt;
                res.send(&#039;Successfully registered &#039; + newPlayers[0].playername);&lt;br /&gt;
            }&lt;br /&gt;
        });    &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    playersCollection.find({playername: playername}).toArray(addPlayer);&lt;br /&gt;
}&lt;br /&gt;
exports.start = function(req, res){&lt;br /&gt;
    var playername = req.body.playername;&lt;br /&gt;
    var password = req.body.password;&lt;br /&gt;
&lt;br /&gt;
    playersCollection.findOne({playername: playername}, function(err, player) {&lt;br /&gt;
        if (err || !player){&lt;br /&gt;
            req.session.destroy(function(err) {&lt;br /&gt;
                res.redirect(&amp;quot;/?error=invalid playername or password&amp;quot;); &lt;br /&gt;
            });&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (password === player.password) {&lt;br /&gt;
            req.session.player = player;&lt;br /&gt;
            delete req.session.player._id;&lt;br /&gt;
            res.redirect(&amp;quot;/&amp;quot; + player.room);&lt;br /&gt;
        } else {&lt;br /&gt;
            req.session.destroy(function(err) {&lt;br /&gt;
                res.redirect(&amp;quot;/?error=invalid playername or password&amp;quot;);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
exports.quit = function(req, res){&lt;br /&gt;
    req.session.destroy(function(err){&lt;br /&gt;
        if(err){&lt;br /&gt;
            console.log(&amp;quot;Error: %s&amp;quot;, err);&lt;br /&gt;
        }&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
    }); &lt;br /&gt;
}&lt;br /&gt;
exports.makeRoomHandler = function(roomName) {&lt;br /&gt;
    var handler = function(req, res) { //without &#039;var&#039; handler becomes a global variable&lt;br /&gt;
        if (req.session.player) {&lt;br /&gt;
            var player = req.session.player;&lt;br /&gt;
            player.room = roomName;&lt;br /&gt;
            playersCollection.update({&amp;quot;playername&amp;quot;: player.playername},&lt;br /&gt;
                                     player, function(err, count) {&lt;br /&gt;
                                         if (err) {&lt;br /&gt;
                                             console.log(&lt;br /&gt;
                                                 &amp;quot;Couldn&#039;t save player state&amp;quot;);&lt;br /&gt;
                                         }&lt;br /&gt;
                                     });&lt;br /&gt;
            roomsCollection.findOne(&lt;br /&gt;
                {name: roomName},&lt;br /&gt;
                function(err, room) {&lt;br /&gt;
                    if (err || !room) {&lt;br /&gt;
                        throw &amp;quot;Couldn&#039;t find room &amp;quot; + roomName;&lt;br /&gt;
                    }&lt;br /&gt;
                    res.render(&amp;quot;room.jade&amp;quot;, room); //renders an html page with room.jade template&lt;br /&gt;
                }&lt;br /&gt;
            );&lt;br /&gt;
        } else {&lt;br /&gt;
            res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return handler;&lt;br /&gt;
}&lt;br /&gt;
exports.getRooms = function() {&lt;br /&gt;
    return roomsCollection.find({name: &amp;quot;roomList&amp;quot;}); //finds all the rooms with the name in the roomlist&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===public/javascripts/home.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
$(function(){&lt;br /&gt;
	$(&amp;quot;#register&amp;quot;).on(&amp;quot;click&amp;quot;,function(){&lt;br /&gt;
		var $form = $(&amp;quot;form&amp;quot;);&lt;br /&gt;
		$form.attr(&amp;quot;action&amp;quot;,&amp;quot;/register&amp;quot;);&lt;br /&gt;
		$form.submit();&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/layout.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
doctype html&lt;br /&gt;
html&lt;br /&gt;
  head&lt;br /&gt;
    title= title&lt;br /&gt;
    script(src=&#039;/vendor/jquery/jquery.js&#039;)&lt;br /&gt;
    script(&#039;vendor/bootstrap/dist/js/bootstrap.js&#039;)&lt;br /&gt;
    link(rel=&#039;stylesheet&#039;, href=&#039;/vendor/bootstrap/dist/css/bootstrap.css&#039;)&lt;br /&gt;
    link(rel=&#039;stylesheet&#039;, href=&#039;/stylesheets/style.css&#039;)&lt;br /&gt;
    block header  &lt;br /&gt;
  body&lt;br /&gt;
    block content&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/index.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
extends layout&lt;br /&gt;
&lt;br /&gt;
block header&lt;br /&gt;
  script(src=&#039;/javascripts/home.js&#039;)&lt;br /&gt;
&lt;br /&gt;
block content&lt;br /&gt;
  h1= title&lt;br /&gt;
  - if(error)&lt;br /&gt;
    div.alert-error #{error}&lt;br /&gt;
  p Please log in&lt;br /&gt;
  div&lt;br /&gt;
    form(action=&amp;quot;/start&amp;quot;, method=&amp;quot;post&amp;quot;)&lt;br /&gt;
        div.control-group.input-append&lt;br /&gt;
            input(type=&amp;quot;text&amp;quot;, name=&amp;quot;playername&amp;quot;)&lt;br /&gt;
            label.add-on(for=&amp;quot;playername&amp;quot;) Player Name&lt;br /&gt;
        div.control-group.input-append&lt;br /&gt;
            input(type=&amp;quot;password&amp;quot;, name=&amp;quot;password&amp;quot;)&lt;br /&gt;
            label.add-on(for=&amp;quot;password&amp;quot;) Password&lt;br /&gt;
            &lt;br /&gt;
        button(type=&amp;quot;submit&amp;quot;) Start&lt;br /&gt;
        button#register(type=&amp;quot;button&amp;quot;) Register&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/room.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
extends layout&lt;br /&gt;
&lt;br /&gt;
block content&lt;br /&gt;
  h1= title&lt;br /&gt;
  p #{description}&lt;br /&gt;
  p Go to:&lt;br /&gt;
  ul&lt;br /&gt;
    each theExit in roomExits&lt;br /&gt;
      li&lt;br /&gt;
        a(href= theExit) #{theExit}&lt;br /&gt;
  form(action=&amp;quot;/quit&amp;quot;, method=&amp;quot;post&amp;quot;)&lt;br /&gt;
     button(type=&amp;quot;submit&amp;quot;) Quit&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Midterm_Review&amp;diff=18827</id>
		<title>WebFund 2014W Midterm Review</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Midterm_Review&amp;diff=18827"/>
		<updated>2014-03-13T17:45:23Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on Feb. 12, 2014 is available:&lt;br /&gt;
* [http://www.screencast.com/t/9bmB5dTEoC small at Screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/nC3DlJrkoqt large at Screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Midterm_Review_-_20140212_150208_27.mp4 Original at CUOL]&lt;br /&gt;
&lt;br /&gt;
The midterm will be based on [http://homeostasis.scs.carleton.ca/~soma/webfund-2014w/midterm/small-adventure.zip small-adventure], a version of &amp;lt;tt&amp;gt;adventure-demo&amp;lt;/tt&amp;gt; that has been simplified by removing the use of cryptography (https and bcrypt) along with a few other minor tweaks to reduce the size of the source code.&lt;br /&gt;
&lt;br /&gt;
No new tutorial this week; however, two TAs/instructors will be in the lab on Thursday 4-5:30 and Friday 8:30-10 to answer last minute questions.&lt;br /&gt;
&lt;br /&gt;
==Source for small-adventure==&lt;br /&gt;
&lt;br /&gt;
===app.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var express = require(&#039;express&#039;); //requires the express module&lt;br /&gt;
var routes = require(&#039;./routes&#039;); //same as (&#039;/routes/index.js&#039;). The require() method returns the exports object&lt;br /&gt;
var path = require(&#039;path&#039;); //imports the path module, or path.join will not be defined&lt;br /&gt;
var http = require(&#039;http&#039;); //requires the http module&lt;br /&gt;
var MongoStore = require(&#039;connect-mongo&#039;)(express);&lt;br /&gt;
&lt;br /&gt;
var app = express(); //creates an express object instance and assigns the app variable to it.&lt;br /&gt;
&lt;br /&gt;
app.set(&#039;port&#039;, process.env.PORT || 3000); //listens on PORT environment variable OR port 3000 if not defined&lt;br /&gt;
app.set(&#039;views&#039;, path.join(__dirname, &#039;views&#039;)); //sets the location for application views&lt;br /&gt;
app.set(&#039;view engine&#039;, &#039;jade&#039;); //sets the view engine, Jade&lt;br /&gt;
app.use(express.favicon()); //can specify where you want favicon to be found in the parameters. e.g (_dirname + &#039;public/favicon.ico&#039;)&lt;br /&gt;
app.use(express.logger(&#039;dev&#039;)); //logging requests using predefined log format &#039;dev&#039;. This will generate a detail log.&lt;br /&gt;
app.use(express.urlencoded()); //The body of HTTP post requests. Parses the incoming request body, converting it into request object properties&lt;br /&gt;
&lt;br /&gt;
app.use(express.cookieParser()); &lt;br /&gt;
app.use(express.session({&lt;br /&gt;
    cookie: {maxAge: 60000 * 20} // 20 minutes&lt;br /&gt;
    , secret: &amp;quot;Shh... I&#039;m a secret&amp;quot; //This is the secret that prevents attackers from creating their own fake session identifiers&lt;br /&gt;
    , store: new MongoStore({db: &amp;quot;adventure-demo&amp;quot;})&lt;br /&gt;
}));&lt;br /&gt;
&lt;br /&gt;
app.use(app.router);&lt;br /&gt;
app.use(express.static(path.join(__dirname, &#039;public&#039;)));&lt;br /&gt;
&lt;br /&gt;
if (&#039;development&#039; == app.get(&#039;env&#039;)) {&lt;br /&gt;
  app.use(express.errorHandler());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
app.get(&#039;/&#039;, routes.redirectLoggedIn, routes.index);&lt;br /&gt;
app.post(&amp;quot;/register&amp;quot;, routes.register);&lt;br /&gt;
app.post(&amp;quot;/start&amp;quot;, routes.start);&lt;br /&gt;
app.post(&amp;quot;/quit&amp;quot;, routes.quit);&lt;br /&gt;
&lt;br /&gt;
var createRooms = function() {&lt;br /&gt;
    var i, theRoom;&lt;br /&gt;
&lt;br /&gt;
    routes.getRooms().toArray(&lt;br /&gt;
        function(err, docs) {&lt;br /&gt;
            if (err) {&lt;br /&gt;
                throw &amp;quot;Couldn&#039;t find active room list&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            var activeRooms = docs[0].activeRooms;&lt;br /&gt;
&lt;br /&gt;
            activeRooms.forEach(function(roomName) {&lt;br /&gt;
                console.log(&#039;Creating room: &#039; + roomName);&lt;br /&gt;
                app.get(&#039;/&#039; + roomName,&lt;br /&gt;
                        routes.makeRoomHandler(roomName));&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
routes.connectToDBs(createRooms);&lt;br /&gt;
&lt;br /&gt;
http.createServer(app).listen(app.get(&#039;port&#039;), function(){&lt;br /&gt;
  console.log(&#039;Express server listening on port &#039; + app.get(&#039;port&#039;) +&lt;br /&gt;
              &#039; in &#039; + app.get(&#039;env&#039;) + &#039; mode.&#039;);&lt;br /&gt;
});&lt;br /&gt;
//1) createServer(): a method of http that creates and returns a server object&lt;br /&gt;
//2) listen(): a method at the returned server object that starts the web server listening on a given port&lt;br /&gt;
//3) app.get(): returns the port to listen on&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===routes/index.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var mc = require(&#039;mongodb&#039;).MongoClient;&lt;br /&gt;
var playersCollection, roomsCollection;&lt;br /&gt;
exports.connectToDBs = function(callback) {&lt;br /&gt;
    mc.connect(&#039;mongodb://localhost/adventure-demo&#039;, function(err, db) {&lt;br /&gt;
        if (err) {&lt;br /&gt;
            throw err;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        playersCollection = db.collection(&#039;players&#039;);&lt;br /&gt;
        roomsCollection = db.collection(&#039;rooms&#039;);&lt;br /&gt;
&lt;br /&gt;
        callback();&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
exports.index = function(req, res){&lt;br /&gt;
    res.render(&#039;index&#039;, { title: &#039;COMP 2406 Small Adventure Demo&#039;,&lt;br /&gt;
                          error: req.query.error });&lt;br /&gt;
}&lt;br /&gt;
exports.redirectLoggedIn = function(req, res, next) {&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot; + req.session.player.room);&lt;br /&gt;
    } else {&lt;br /&gt;
        next();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
exports.redirectNotLoggedIn = function(req, res, next) {&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
        next();&lt;br /&gt;
    } else {&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
exports.register = function(req, res) {&lt;br /&gt;
    var playername = req.body.playername;&lt;br /&gt;
    var password = req.body.password;&lt;br /&gt;
&lt;br /&gt;
    var addPlayer = function(err, players) {&lt;br /&gt;
        if(players.length!=0){&lt;br /&gt;
            res.redirect(&amp;quot;/?error=player already exists&amp;quot;);      &lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        var newPlayer = {&lt;br /&gt;
            playername: playername,&lt;br /&gt;
            password: password,&lt;br /&gt;
            room: &amp;quot;bridge&amp;quot;&lt;br /&gt;
        };&lt;br /&gt;
                &lt;br /&gt;
        playersCollection.insert(newPlayer, function(err, newPlayers){&lt;br /&gt;
            if (err) {&lt;br /&gt;
                throw err;&lt;br /&gt;
            } else {&lt;br /&gt;
                res.send(&#039;Successfully registered &#039; + newPlayers[0].playername);&lt;br /&gt;
            }&lt;br /&gt;
        });    &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    playersCollection.find({playername: playername}).toArray(addPlayer);&lt;br /&gt;
}&lt;br /&gt;
exports.start = function(req, res){&lt;br /&gt;
    var playername = req.body.playername;&lt;br /&gt;
    var password = req.body.password;&lt;br /&gt;
&lt;br /&gt;
    playersCollection.findOne({playername: playername}, function(err, player) {&lt;br /&gt;
        if (err || !player){&lt;br /&gt;
            req.session.destroy(function(err) {&lt;br /&gt;
                res.redirect(&amp;quot;/?error=invalid playername or password&amp;quot;); &lt;br /&gt;
            });&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (password === player.password) {&lt;br /&gt;
            req.session.player = player;&lt;br /&gt;
            delete req.session.player._id;&lt;br /&gt;
            res.redirect(&amp;quot;/&amp;quot; + player.room);&lt;br /&gt;
        } else {&lt;br /&gt;
            req.session.destroy(function(err) {&lt;br /&gt;
                res.redirect(&amp;quot;/?error=invalid playername or password&amp;quot;);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
exports.quit = function(req, res){&lt;br /&gt;
    req.session.destroy(function(err){&lt;br /&gt;
        if(err){&lt;br /&gt;
            console.log(&amp;quot;Error: %s&amp;quot;, err);&lt;br /&gt;
        }&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
    }); &lt;br /&gt;
}&lt;br /&gt;
exports.makeRoomHandler = function(roomName) {&lt;br /&gt;
    var handler = function(req, res) {&lt;br /&gt;
        if (req.session.player) {&lt;br /&gt;
            var player = req.session.player;&lt;br /&gt;
            player.room = roomName;&lt;br /&gt;
            playersCollection.update({&amp;quot;playername&amp;quot;: player.playername},&lt;br /&gt;
                                     player, function(err, count) {&lt;br /&gt;
                                         if (err) {&lt;br /&gt;
                                             console.log(&lt;br /&gt;
                                                 &amp;quot;Couldn&#039;t save player state&amp;quot;);&lt;br /&gt;
                                         }&lt;br /&gt;
                                     });&lt;br /&gt;
            roomsCollection.findOne(&lt;br /&gt;
                {name: roomName},&lt;br /&gt;
                function(err, room) {&lt;br /&gt;
                    if (err || !room) {&lt;br /&gt;
                        throw &amp;quot;Couldn&#039;t find room &amp;quot; + roomName;&lt;br /&gt;
                    }&lt;br /&gt;
                    res.render(&amp;quot;room.jade&amp;quot;, room);&lt;br /&gt;
                }&lt;br /&gt;
            );&lt;br /&gt;
        } else {&lt;br /&gt;
            res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return handler;&lt;br /&gt;
}&lt;br /&gt;
exports.getRooms = function() {&lt;br /&gt;
    return roomsCollection.find({name: &amp;quot;roomList&amp;quot;});&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===public/javascripts/home.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
$(function(){&lt;br /&gt;
	$(&amp;quot;#register&amp;quot;).on(&amp;quot;click&amp;quot;,function(){&lt;br /&gt;
		var $form = $(&amp;quot;form&amp;quot;);&lt;br /&gt;
		$form.attr(&amp;quot;action&amp;quot;,&amp;quot;/register&amp;quot;);&lt;br /&gt;
		$form.submit();&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/layout.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
doctype html&lt;br /&gt;
html&lt;br /&gt;
  head&lt;br /&gt;
    title= title&lt;br /&gt;
    script(src=&#039;/vendor/jquery/jquery.js&#039;)&lt;br /&gt;
    script(&#039;vendor/bootstrap/dist/js/bootstrap.js&#039;)&lt;br /&gt;
    link(rel=&#039;stylesheet&#039;, href=&#039;/vendor/bootstrap/dist/css/bootstrap.css&#039;)&lt;br /&gt;
    link(rel=&#039;stylesheet&#039;, href=&#039;/stylesheets/style.css&#039;)&lt;br /&gt;
    block header  &lt;br /&gt;
  body&lt;br /&gt;
    block content&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/index.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
extends layout&lt;br /&gt;
&lt;br /&gt;
block header&lt;br /&gt;
  script(src=&#039;/javascripts/home.js&#039;)&lt;br /&gt;
&lt;br /&gt;
block content&lt;br /&gt;
  h1= title&lt;br /&gt;
  - if(error)&lt;br /&gt;
    div.alert-error #{error}&lt;br /&gt;
  p Please log in&lt;br /&gt;
  div&lt;br /&gt;
    form(action=&amp;quot;/start&amp;quot;, method=&amp;quot;post&amp;quot;)&lt;br /&gt;
        div.control-group.input-append&lt;br /&gt;
            input(type=&amp;quot;text&amp;quot;, name=&amp;quot;playername&amp;quot;)&lt;br /&gt;
            label.add-on(for=&amp;quot;playername&amp;quot;) Player Name&lt;br /&gt;
        div.control-group.input-append&lt;br /&gt;
            input(type=&amp;quot;password&amp;quot;, name=&amp;quot;password&amp;quot;)&lt;br /&gt;
            label.add-on(for=&amp;quot;password&amp;quot;) Password&lt;br /&gt;
            &lt;br /&gt;
        button(type=&amp;quot;submit&amp;quot;) Start&lt;br /&gt;
        button#register(type=&amp;quot;button&amp;quot;) Register&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/room.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
extends layout&lt;br /&gt;
&lt;br /&gt;
block content&lt;br /&gt;
  h1= title&lt;br /&gt;
  p #{description}&lt;br /&gt;
  p Go to:&lt;br /&gt;
  ul&lt;br /&gt;
    each theExit in roomExits&lt;br /&gt;
      li&lt;br /&gt;
        a(href= theExit) #{theExit}&lt;br /&gt;
  form(action=&amp;quot;/quit&amp;quot;, method=&amp;quot;post&amp;quot;)&lt;br /&gt;
     button(type=&amp;quot;submit&amp;quot;) Quit&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Midterm_Review&amp;diff=18826</id>
		<title>WebFund 2014W Midterm Review</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Midterm_Review&amp;diff=18826"/>
		<updated>2014-03-13T17:32:17Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on Feb. 12, 2014 is available:&lt;br /&gt;
* [http://www.screencast.com/t/9bmB5dTEoC small at Screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/nC3DlJrkoqt large at Screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Midterm_Review_-_20140212_150208_27.mp4 Original at CUOL]&lt;br /&gt;
&lt;br /&gt;
The midterm will be based on [http://homeostasis.scs.carleton.ca/~soma/webfund-2014w/midterm/small-adventure.zip small-adventure], a version of &amp;lt;tt&amp;gt;adventure-demo&amp;lt;/tt&amp;gt; that has been simplified by removing the use of cryptography (https and bcrypt) along with a few other minor tweaks to reduce the size of the source code.&lt;br /&gt;
&lt;br /&gt;
No new tutorial this week; however, two TAs/instructors will be in the lab on Thursday 4-5:30 and Friday 8:30-10 to answer last minute questions.&lt;br /&gt;
&lt;br /&gt;
==Source for small-adventure==&lt;br /&gt;
&lt;br /&gt;
===app.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var express = require(&#039;express&#039;);&lt;br /&gt;
var routes = require(&#039;./routes&#039;); //same as (&#039;/routes/index.js&#039;). The require() method returns the exports object&lt;br /&gt;
var path = require(&#039;path&#039;); //imports the path module, or path.join will not be defined&lt;br /&gt;
var http = require(&#039;http&#039;);&lt;br /&gt;
var MongoStore = require(&#039;connect-mongo&#039;)(express);&lt;br /&gt;
&lt;br /&gt;
var app = express(); //creates an express object instance and assigns the app variable to it.&lt;br /&gt;
&lt;br /&gt;
app.set(&#039;port&#039;, process.env.PORT || 3000); //listens on PORT environment variable OR port 3000 if not defined&lt;br /&gt;
app.set(&#039;views&#039;, path.join(__dirname, &#039;views&#039;));&lt;br /&gt;
app.set(&#039;view engine&#039;, &#039;jade&#039;);&lt;br /&gt;
app.use(express.favicon());&lt;br /&gt;
app.use(express.logger(&#039;dev&#039;));&lt;br /&gt;
app.use(express.urlencoded());&lt;br /&gt;
&lt;br /&gt;
app.use(express.cookieParser());&lt;br /&gt;
app.use(express.session({&lt;br /&gt;
    cookie: {maxAge: 60000 * 20} // 20 minutes&lt;br /&gt;
    , secret: &amp;quot;Shh... I&#039;m a secret&amp;quot;&lt;br /&gt;
    , store: new MongoStore({db: &amp;quot;adventure-demo&amp;quot;})&lt;br /&gt;
}));&lt;br /&gt;
&lt;br /&gt;
app.use(app.router);&lt;br /&gt;
app.use(express.static(path.join(__dirname, &#039;public&#039;)));&lt;br /&gt;
&lt;br /&gt;
if (&#039;development&#039; == app.get(&#039;env&#039;)) {&lt;br /&gt;
  app.use(express.errorHandler());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
app.get(&#039;/&#039;, routes.redirectLoggedIn, routes.index);&lt;br /&gt;
app.post(&amp;quot;/register&amp;quot;, routes.register);&lt;br /&gt;
app.post(&amp;quot;/start&amp;quot;, routes.start);&lt;br /&gt;
app.post(&amp;quot;/quit&amp;quot;, routes.quit);&lt;br /&gt;
&lt;br /&gt;
var createRooms = function() {&lt;br /&gt;
    var i, theRoom;&lt;br /&gt;
&lt;br /&gt;
    routes.getRooms().toArray(&lt;br /&gt;
        function(err, docs) {&lt;br /&gt;
            if (err) {&lt;br /&gt;
                throw &amp;quot;Couldn&#039;t find active room list&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            var activeRooms = docs[0].activeRooms;&lt;br /&gt;
&lt;br /&gt;
            activeRooms.forEach(function(roomName) {&lt;br /&gt;
                console.log(&#039;Creating room: &#039; + roomName);&lt;br /&gt;
                app.get(&#039;/&#039; + roomName,&lt;br /&gt;
                        routes.makeRoomHandler(roomName));&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
routes.connectToDBs(createRooms);&lt;br /&gt;
&lt;br /&gt;
http.createServer(app).listen(app.get(&#039;port&#039;), function(){&lt;br /&gt;
  console.log(&#039;Express server listening on port &#039; + app.get(&#039;port&#039;) +&lt;br /&gt;
              &#039; in &#039; + app.get(&#039;env&#039;) + &#039; mode.&#039;);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===routes/index.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var mc = require(&#039;mongodb&#039;).MongoClient;&lt;br /&gt;
var playersCollection, roomsCollection;&lt;br /&gt;
exports.connectToDBs = function(callback) {&lt;br /&gt;
    mc.connect(&#039;mongodb://localhost/adventure-demo&#039;, function(err, db) {&lt;br /&gt;
        if (err) {&lt;br /&gt;
            throw err;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        playersCollection = db.collection(&#039;players&#039;);&lt;br /&gt;
        roomsCollection = db.collection(&#039;rooms&#039;);&lt;br /&gt;
&lt;br /&gt;
        callback();&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
exports.index = function(req, res){&lt;br /&gt;
    res.render(&#039;index&#039;, { title: &#039;COMP 2406 Small Adventure Demo&#039;,&lt;br /&gt;
                          error: req.query.error });&lt;br /&gt;
}&lt;br /&gt;
exports.redirectLoggedIn = function(req, res, next) {&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot; + req.session.player.room);&lt;br /&gt;
    } else {&lt;br /&gt;
        next();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
exports.redirectNotLoggedIn = function(req, res, next) {&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
        next();&lt;br /&gt;
    } else {&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
exports.register = function(req, res) {&lt;br /&gt;
    var playername = req.body.playername;&lt;br /&gt;
    var password = req.body.password;&lt;br /&gt;
&lt;br /&gt;
    var addPlayer = function(err, players) {&lt;br /&gt;
        if(players.length!=0){&lt;br /&gt;
            res.redirect(&amp;quot;/?error=player already exists&amp;quot;);      &lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        var newPlayer = {&lt;br /&gt;
            playername: playername,&lt;br /&gt;
            password: password,&lt;br /&gt;
            room: &amp;quot;bridge&amp;quot;&lt;br /&gt;
        };&lt;br /&gt;
                &lt;br /&gt;
        playersCollection.insert(newPlayer, function(err, newPlayers){&lt;br /&gt;
            if (err) {&lt;br /&gt;
                throw err;&lt;br /&gt;
            } else {&lt;br /&gt;
                res.send(&#039;Successfully registered &#039; + newPlayers[0].playername);&lt;br /&gt;
            }&lt;br /&gt;
        });    &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    playersCollection.find({playername: playername}).toArray(addPlayer);&lt;br /&gt;
}&lt;br /&gt;
exports.start = function(req, res){&lt;br /&gt;
    var playername = req.body.playername;&lt;br /&gt;
    var password = req.body.password;&lt;br /&gt;
&lt;br /&gt;
    playersCollection.findOne({playername: playername}, function(err, player) {&lt;br /&gt;
        if (err || !player){&lt;br /&gt;
            req.session.destroy(function(err) {&lt;br /&gt;
                res.redirect(&amp;quot;/?error=invalid playername or password&amp;quot;); &lt;br /&gt;
            });&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (password === player.password) {&lt;br /&gt;
            req.session.player = player;&lt;br /&gt;
            delete req.session.player._id;&lt;br /&gt;
            res.redirect(&amp;quot;/&amp;quot; + player.room);&lt;br /&gt;
        } else {&lt;br /&gt;
            req.session.destroy(function(err) {&lt;br /&gt;
                res.redirect(&amp;quot;/?error=invalid playername or password&amp;quot;);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
exports.quit = function(req, res){&lt;br /&gt;
    req.session.destroy(function(err){&lt;br /&gt;
        if(err){&lt;br /&gt;
            console.log(&amp;quot;Error: %s&amp;quot;, err);&lt;br /&gt;
        }&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
    }); &lt;br /&gt;
}&lt;br /&gt;
exports.makeRoomHandler = function(roomName) {&lt;br /&gt;
    var handler = function(req, res) {&lt;br /&gt;
        if (req.session.player) {&lt;br /&gt;
            var player = req.session.player;&lt;br /&gt;
            player.room = roomName;&lt;br /&gt;
            playersCollection.update({&amp;quot;playername&amp;quot;: player.playername},&lt;br /&gt;
                                     player, function(err, count) {&lt;br /&gt;
                                         if (err) {&lt;br /&gt;
                                             console.log(&lt;br /&gt;
                                                 &amp;quot;Couldn&#039;t save player state&amp;quot;);&lt;br /&gt;
                                         }&lt;br /&gt;
                                     });&lt;br /&gt;
            roomsCollection.findOne(&lt;br /&gt;
                {name: roomName},&lt;br /&gt;
                function(err, room) {&lt;br /&gt;
                    if (err || !room) {&lt;br /&gt;
                        throw &amp;quot;Couldn&#039;t find room &amp;quot; + roomName;&lt;br /&gt;
                    }&lt;br /&gt;
                    res.render(&amp;quot;room.jade&amp;quot;, room);&lt;br /&gt;
                }&lt;br /&gt;
            );&lt;br /&gt;
        } else {&lt;br /&gt;
            res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return handler;&lt;br /&gt;
}&lt;br /&gt;
exports.getRooms = function() {&lt;br /&gt;
    return roomsCollection.find({name: &amp;quot;roomList&amp;quot;});&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===public/javascripts/home.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
$(function(){&lt;br /&gt;
	$(&amp;quot;#register&amp;quot;).on(&amp;quot;click&amp;quot;,function(){&lt;br /&gt;
		var $form = $(&amp;quot;form&amp;quot;);&lt;br /&gt;
		$form.attr(&amp;quot;action&amp;quot;,&amp;quot;/register&amp;quot;);&lt;br /&gt;
		$form.submit();&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/layout.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
doctype html&lt;br /&gt;
html&lt;br /&gt;
  head&lt;br /&gt;
    title= title&lt;br /&gt;
    script(src=&#039;/vendor/jquery/jquery.js&#039;)&lt;br /&gt;
    script(&#039;vendor/bootstrap/dist/js/bootstrap.js&#039;)&lt;br /&gt;
    link(rel=&#039;stylesheet&#039;, href=&#039;/vendor/bootstrap/dist/css/bootstrap.css&#039;)&lt;br /&gt;
    link(rel=&#039;stylesheet&#039;, href=&#039;/stylesheets/style.css&#039;)&lt;br /&gt;
    block header  &lt;br /&gt;
  body&lt;br /&gt;
    block content&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/index.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
extends layout&lt;br /&gt;
&lt;br /&gt;
block header&lt;br /&gt;
  script(src=&#039;/javascripts/home.js&#039;)&lt;br /&gt;
&lt;br /&gt;
block content&lt;br /&gt;
  h1= title&lt;br /&gt;
  - if(error)&lt;br /&gt;
    div.alert-error #{error}&lt;br /&gt;
  p Please log in&lt;br /&gt;
  div&lt;br /&gt;
    form(action=&amp;quot;/start&amp;quot;, method=&amp;quot;post&amp;quot;)&lt;br /&gt;
        div.control-group.input-append&lt;br /&gt;
            input(type=&amp;quot;text&amp;quot;, name=&amp;quot;playername&amp;quot;)&lt;br /&gt;
            label.add-on(for=&amp;quot;playername&amp;quot;) Player Name&lt;br /&gt;
        div.control-group.input-append&lt;br /&gt;
            input(type=&amp;quot;password&amp;quot;, name=&amp;quot;password&amp;quot;)&lt;br /&gt;
            label.add-on(for=&amp;quot;password&amp;quot;) Password&lt;br /&gt;
            &lt;br /&gt;
        button(type=&amp;quot;submit&amp;quot;) Start&lt;br /&gt;
        button#register(type=&amp;quot;button&amp;quot;) Register&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/room.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
extends layout&lt;br /&gt;
&lt;br /&gt;
block content&lt;br /&gt;
  h1= title&lt;br /&gt;
  p #{description}&lt;br /&gt;
  p Go to:&lt;br /&gt;
  ul&lt;br /&gt;
    each theExit in roomExits&lt;br /&gt;
      li&lt;br /&gt;
        a(href= theExit) #{theExit}&lt;br /&gt;
  form(action=&amp;quot;/quit&amp;quot;, method=&amp;quot;post&amp;quot;)&lt;br /&gt;
     button(type=&amp;quot;submit&amp;quot;) Quit&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Midterm_Review&amp;diff=18825</id>
		<title>WebFund 2014W Midterm Review</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Midterm_Review&amp;diff=18825"/>
		<updated>2014-03-13T17:26:08Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on Feb. 12, 2014 is available:&lt;br /&gt;
* [http://www.screencast.com/t/9bmB5dTEoC small at Screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/nC3DlJrkoqt large at Screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Midterm_Review_-_20140212_150208_27.mp4 Original at CUOL]&lt;br /&gt;
&lt;br /&gt;
The midterm will be based on [http://homeostasis.scs.carleton.ca/~soma/webfund-2014w/midterm/small-adventure.zip small-adventure], a version of &amp;lt;tt&amp;gt;adventure-demo&amp;lt;/tt&amp;gt; that has been simplified by removing the use of cryptography (https and bcrypt) along with a few other minor tweaks to reduce the size of the source code.&lt;br /&gt;
&lt;br /&gt;
No new tutorial this week; however, two TAs/instructors will be in the lab on Thursday 4-5:30 and Friday 8:30-10 to answer last minute questions.&lt;br /&gt;
&lt;br /&gt;
==Source for small-adventure==&lt;br /&gt;
&lt;br /&gt;
===app.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var express = require(&#039;express&#039;);&lt;br /&gt;
var routes = require(&#039;./routes&#039;); //the require&lt;br /&gt;
var path = require(&#039;path&#039;);&lt;br /&gt;
var http = require(&#039;http&#039;);&lt;br /&gt;
var MongoStore = require(&#039;connect-mongo&#039;)(express);&lt;br /&gt;
&lt;br /&gt;
var app = express();&lt;br /&gt;
&lt;br /&gt;
app.set(&#039;port&#039;, process.env.PORT || 3000);&lt;br /&gt;
app.set(&#039;views&#039;, path.join(__dirname, &#039;views&#039;));&lt;br /&gt;
app.set(&#039;view engine&#039;, &#039;jade&#039;);&lt;br /&gt;
app.use(express.favicon());&lt;br /&gt;
app.use(express.logger(&#039;dev&#039;));&lt;br /&gt;
app.use(express.urlencoded());&lt;br /&gt;
&lt;br /&gt;
app.use(express.cookieParser());&lt;br /&gt;
app.use(express.session({&lt;br /&gt;
    cookie: {maxAge: 60000 * 20} // 20 minutes&lt;br /&gt;
    , secret: &amp;quot;Shh... I&#039;m a secret&amp;quot;&lt;br /&gt;
    , store: new MongoStore({db: &amp;quot;adventure-demo&amp;quot;})&lt;br /&gt;
}));&lt;br /&gt;
&lt;br /&gt;
app.use(app.router);&lt;br /&gt;
app.use(express.static(path.join(__dirname, &#039;public&#039;)));&lt;br /&gt;
&lt;br /&gt;
if (&#039;development&#039; == app.get(&#039;env&#039;)) {&lt;br /&gt;
  app.use(express.errorHandler());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
app.get(&#039;/&#039;, routes.redirectLoggedIn, routes.index);&lt;br /&gt;
app.post(&amp;quot;/register&amp;quot;, routes.register);&lt;br /&gt;
app.post(&amp;quot;/start&amp;quot;, routes.start);&lt;br /&gt;
app.post(&amp;quot;/quit&amp;quot;, routes.quit);&lt;br /&gt;
&lt;br /&gt;
var createRooms = function() {&lt;br /&gt;
    var i, theRoom;&lt;br /&gt;
&lt;br /&gt;
    routes.getRooms().toArray(&lt;br /&gt;
        function(err, docs) {&lt;br /&gt;
            if (err) {&lt;br /&gt;
                throw &amp;quot;Couldn&#039;t find active room list&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            var activeRooms = docs[0].activeRooms;&lt;br /&gt;
&lt;br /&gt;
            activeRooms.forEach(function(roomName) {&lt;br /&gt;
                console.log(&#039;Creating room: &#039; + roomName);&lt;br /&gt;
                app.get(&#039;/&#039; + roomName,&lt;br /&gt;
                        routes.makeRoomHandler(roomName));&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
routes.connectToDBs(createRooms);&lt;br /&gt;
&lt;br /&gt;
http.createServer(app).listen(app.get(&#039;port&#039;), function(){&lt;br /&gt;
  console.log(&#039;Express server listening on port &#039; + app.get(&#039;port&#039;) +&lt;br /&gt;
              &#039; in &#039; + app.get(&#039;env&#039;) + &#039; mode.&#039;);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===routes/index.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var mc = require(&#039;mongodb&#039;).MongoClient;&lt;br /&gt;
var playersCollection, roomsCollection;&lt;br /&gt;
exports.connectToDBs = function(callback) {&lt;br /&gt;
    mc.connect(&#039;mongodb://localhost/adventure-demo&#039;, function(err, db) {&lt;br /&gt;
        if (err) {&lt;br /&gt;
            throw err;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        playersCollection = db.collection(&#039;players&#039;);&lt;br /&gt;
        roomsCollection = db.collection(&#039;rooms&#039;);&lt;br /&gt;
&lt;br /&gt;
        callback();&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
exports.index = function(req, res){&lt;br /&gt;
    res.render(&#039;index&#039;, { title: &#039;COMP 2406 Small Adventure Demo&#039;,&lt;br /&gt;
                          error: req.query.error });&lt;br /&gt;
}&lt;br /&gt;
exports.redirectLoggedIn = function(req, res, next) {&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot; + req.session.player.room);&lt;br /&gt;
    } else {&lt;br /&gt;
        next();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
exports.redirectNotLoggedIn = function(req, res, next) {&lt;br /&gt;
    if (req.session.player) {&lt;br /&gt;
        next();&lt;br /&gt;
    } else {&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
exports.register = function(req, res) {&lt;br /&gt;
    var playername = req.body.playername;&lt;br /&gt;
    var password = req.body.password;&lt;br /&gt;
&lt;br /&gt;
    var addPlayer = function(err, players) {&lt;br /&gt;
        if(players.length!=0){&lt;br /&gt;
            res.redirect(&amp;quot;/?error=player already exists&amp;quot;);      &lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        var newPlayer = {&lt;br /&gt;
            playername: playername,&lt;br /&gt;
            password: password,&lt;br /&gt;
            room: &amp;quot;bridge&amp;quot;&lt;br /&gt;
        };&lt;br /&gt;
                &lt;br /&gt;
        playersCollection.insert(newPlayer, function(err, newPlayers){&lt;br /&gt;
            if (err) {&lt;br /&gt;
                throw err;&lt;br /&gt;
            } else {&lt;br /&gt;
                res.send(&#039;Successfully registered &#039; + newPlayers[0].playername);&lt;br /&gt;
            }&lt;br /&gt;
        });    &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    playersCollection.find({playername: playername}).toArray(addPlayer);&lt;br /&gt;
}&lt;br /&gt;
exports.start = function(req, res){&lt;br /&gt;
    var playername = req.body.playername;&lt;br /&gt;
    var password = req.body.password;&lt;br /&gt;
&lt;br /&gt;
    playersCollection.findOne({playername: playername}, function(err, player) {&lt;br /&gt;
        if (err || !player){&lt;br /&gt;
            req.session.destroy(function(err) {&lt;br /&gt;
                res.redirect(&amp;quot;/?error=invalid playername or password&amp;quot;); &lt;br /&gt;
            });&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (password === player.password) {&lt;br /&gt;
            req.session.player = player;&lt;br /&gt;
            delete req.session.player._id;&lt;br /&gt;
            res.redirect(&amp;quot;/&amp;quot; + player.room);&lt;br /&gt;
        } else {&lt;br /&gt;
            req.session.destroy(function(err) {&lt;br /&gt;
                res.redirect(&amp;quot;/?error=invalid playername or password&amp;quot;);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
exports.quit = function(req, res){&lt;br /&gt;
    req.session.destroy(function(err){&lt;br /&gt;
        if(err){&lt;br /&gt;
            console.log(&amp;quot;Error: %s&amp;quot;, err);&lt;br /&gt;
        }&lt;br /&gt;
        res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
    }); &lt;br /&gt;
}&lt;br /&gt;
exports.makeRoomHandler = function(roomName) {&lt;br /&gt;
    var handler = function(req, res) {&lt;br /&gt;
        if (req.session.player) {&lt;br /&gt;
            var player = req.session.player;&lt;br /&gt;
            player.room = roomName;&lt;br /&gt;
            playersCollection.update({&amp;quot;playername&amp;quot;: player.playername},&lt;br /&gt;
                                     player, function(err, count) {&lt;br /&gt;
                                         if (err) {&lt;br /&gt;
                                             console.log(&lt;br /&gt;
                                                 &amp;quot;Couldn&#039;t save player state&amp;quot;);&lt;br /&gt;
                                         }&lt;br /&gt;
                                     });&lt;br /&gt;
            roomsCollection.findOne(&lt;br /&gt;
                {name: roomName},&lt;br /&gt;
                function(err, room) {&lt;br /&gt;
                    if (err || !room) {&lt;br /&gt;
                        throw &amp;quot;Couldn&#039;t find room &amp;quot; + roomName;&lt;br /&gt;
                    }&lt;br /&gt;
                    res.render(&amp;quot;room.jade&amp;quot;, room);&lt;br /&gt;
                }&lt;br /&gt;
            );&lt;br /&gt;
        } else {&lt;br /&gt;
            res.redirect(&amp;quot;/&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return handler;&lt;br /&gt;
}&lt;br /&gt;
exports.getRooms = function() {&lt;br /&gt;
    return roomsCollection.find({name: &amp;quot;roomList&amp;quot;});&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===public/javascripts/home.js===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
$(function(){&lt;br /&gt;
	$(&amp;quot;#register&amp;quot;).on(&amp;quot;click&amp;quot;,function(){&lt;br /&gt;
		var $form = $(&amp;quot;form&amp;quot;);&lt;br /&gt;
		$form.attr(&amp;quot;action&amp;quot;,&amp;quot;/register&amp;quot;);&lt;br /&gt;
		$form.submit();&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/layout.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
doctype html&lt;br /&gt;
html&lt;br /&gt;
  head&lt;br /&gt;
    title= title&lt;br /&gt;
    script(src=&#039;/vendor/jquery/jquery.js&#039;)&lt;br /&gt;
    script(&#039;vendor/bootstrap/dist/js/bootstrap.js&#039;)&lt;br /&gt;
    link(rel=&#039;stylesheet&#039;, href=&#039;/vendor/bootstrap/dist/css/bootstrap.css&#039;)&lt;br /&gt;
    link(rel=&#039;stylesheet&#039;, href=&#039;/stylesheets/style.css&#039;)&lt;br /&gt;
    block header  &lt;br /&gt;
  body&lt;br /&gt;
    block content&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/index.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
extends layout&lt;br /&gt;
&lt;br /&gt;
block header&lt;br /&gt;
  script(src=&#039;/javascripts/home.js&#039;)&lt;br /&gt;
&lt;br /&gt;
block content&lt;br /&gt;
  h1= title&lt;br /&gt;
  - if(error)&lt;br /&gt;
    div.alert-error #{error}&lt;br /&gt;
  p Please log in&lt;br /&gt;
  div&lt;br /&gt;
    form(action=&amp;quot;/start&amp;quot;, method=&amp;quot;post&amp;quot;)&lt;br /&gt;
        div.control-group.input-append&lt;br /&gt;
            input(type=&amp;quot;text&amp;quot;, name=&amp;quot;playername&amp;quot;)&lt;br /&gt;
            label.add-on(for=&amp;quot;playername&amp;quot;) Player Name&lt;br /&gt;
        div.control-group.input-append&lt;br /&gt;
            input(type=&amp;quot;password&amp;quot;, name=&amp;quot;password&amp;quot;)&lt;br /&gt;
            label.add-on(for=&amp;quot;password&amp;quot;) Password&lt;br /&gt;
            &lt;br /&gt;
        button(type=&amp;quot;submit&amp;quot;) Start&lt;br /&gt;
        button#register(type=&amp;quot;button&amp;quot;) Register&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===views/room.jade===&lt;br /&gt;
&amp;lt;source line lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
extends layout&lt;br /&gt;
&lt;br /&gt;
block content&lt;br /&gt;
  h1= title&lt;br /&gt;
  p #{description}&lt;br /&gt;
  p Go to:&lt;br /&gt;
  ul&lt;br /&gt;
    each theExit in roomExits&lt;br /&gt;
      li&lt;br /&gt;
        a(href= theExit) #{theExit}&lt;br /&gt;
  form(action=&amp;quot;/quit&amp;quot;, method=&amp;quot;post&amp;quot;)&lt;br /&gt;
     button(type=&amp;quot;submit&amp;quot;) Quit&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_7&amp;diff=18824</id>
		<title>WebFund 2014W Lecture 7</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_7&amp;diff=18824"/>
		<updated>2014-03-13T17:14:05Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on January 29, 2014 is available:&lt;br /&gt;
* [http://www.screencast.com/t/5lpc5qWqGBU2 Small from screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/x2iAx5KDyj Large from screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Lecture_7_-_20140129_143752_27.mp4 Original from CUOL]&lt;br /&gt;
&lt;br /&gt;
== Databases ==&lt;br /&gt;
why?&lt;br /&gt;
* Persistence - You want to stick around (vs. RAM)&lt;br /&gt;
* Concurrency in writes - (vs. files)&lt;br /&gt;
* Search - (vs. files)&lt;br /&gt;
** Dynamic data should NOT be stored in files.&lt;br /&gt;
&lt;br /&gt;
SQL(Structured Query Language) vs. NoSQL&lt;br /&gt;
* SQL makes queries to databases, assuming queries are highly structured.&lt;br /&gt;
* for relational databases.&lt;br /&gt;
&lt;br /&gt;
What is a structure of a relational database?&lt;br /&gt;
e.g. Tables - relations connect fields between tables&lt;br /&gt;
* rows (records)&lt;br /&gt;
* columns (fields)&lt;br /&gt;
&lt;br /&gt;
With a relational database, you can quickly compare information because of the arrangement of data in columns. The relational database can build completely new tables out of required information from existing tables. In other words, it uses the relationship of similar data to increase the speed and versatility of the database.&lt;br /&gt;
&lt;br /&gt;
By storing this information in another table, the database can create a single small table with the locations that can then be used for a variety of purposes by other tables in the database. A typical large database will contain hundreds or thousands of tables like this all used together to quickly find the exact information needed.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
Table: People&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! ID&lt;br /&gt;
! First Name  &lt;br /&gt;
! Last Name&lt;br /&gt;
! Phone  &lt;br /&gt;
! Email&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Anil&lt;br /&gt;
| Somayaji&lt;br /&gt;
| 555-1212&lt;br /&gt;
| soma@scs.carleton.ca&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Dana&lt;br /&gt;
| Somayaji&lt;br /&gt;
| 555-1212&lt;br /&gt;
| dana@example.ca (should check whether it is a valid address)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Validation Problem:&lt;br /&gt;
* Where to check for bad data?&lt;br /&gt;
* Can do on:&lt;br /&gt;
** Web client (helpful)&lt;br /&gt;
** Web server (must)&lt;br /&gt;
** Database (useful)&lt;br /&gt;
&lt;br /&gt;
Example continued:&lt;br /&gt;
&lt;br /&gt;
Table: Invoices&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Inv. ID&lt;br /&gt;
! Description  &lt;br /&gt;
! Amount&lt;br /&gt;
! Customer  &lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| iPad&lt;br /&gt;
| $700&lt;br /&gt;
| 1  &amp;lt;- Which is Anil in the People table)&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| MacBookPro&lt;br /&gt;
| $1500&lt;br /&gt;
| 2 &amp;lt;- Which is Dana in the People table)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* One relation: Invoice = Customer ID -&amp;gt; People ID&lt;br /&gt;
&lt;br /&gt;
Could ask for simple queries:&lt;br /&gt;
* All records in People with first name == Anil&lt;br /&gt;
* Which customer has spent the most in our store?&lt;br /&gt;
** Sum of all invoices for each customer&lt;br /&gt;
** find max&lt;br /&gt;
&lt;br /&gt;
Indexing:&lt;br /&gt;
* Simplest: sorts specific fields in a table (create secondary keys)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Secondary key&lt;br /&gt;
! Primary key  &lt;br /&gt;
|-&lt;br /&gt;
| First Name &lt;br /&gt;
|  ID&lt;br /&gt;
|-&lt;br /&gt;
| Anil&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| Dana &lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| Annie &lt;br /&gt;
| 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* We want to sort the names Alphabetically using the secondary key.&lt;br /&gt;
&lt;br /&gt;
Transactions:&lt;br /&gt;
* What if I want to change records in multiple tables in a coordinated fashion?&lt;br /&gt;
* Airline example&lt;br /&gt;
** Reserve seat&lt;br /&gt;
** Pay&lt;br /&gt;
** Commit: check that payment and reservation both worked first&lt;br /&gt;
&lt;br /&gt;
NoSQL Databases: No transactions, no real relations&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_7&amp;diff=18823</id>
		<title>WebFund 2014W Lecture 7</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_7&amp;diff=18823"/>
		<updated>2014-03-13T17:09:59Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on January 29, 2014 is available:&lt;br /&gt;
* [http://www.screencast.com/t/5lpc5qWqGBU2 Small from screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/x2iAx5KDyj Large from screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Lecture_7_-_20140129_143752_27.mp4 Original from CUOL]&lt;br /&gt;
&lt;br /&gt;
== Databases ==&lt;br /&gt;
why?&lt;br /&gt;
* Persistence - You want to stick around (vs. RAM)&lt;br /&gt;
* Concurrency in writes - (vs. files)&lt;br /&gt;
* Search - (vs. files)&lt;br /&gt;
** Dynamic data should NOT be stored in files.&lt;br /&gt;
&lt;br /&gt;
SQL(Structured Query Language) vs. NoSQL&lt;br /&gt;
* SQL makes queries to databases, assuming queries are highly structured.&lt;br /&gt;
* for relational databases.&lt;br /&gt;
&lt;br /&gt;
What is a structure of a relational database?&lt;br /&gt;
e.g. Tables - relations connect fields between tables&lt;br /&gt;
* rows (records)&lt;br /&gt;
* columns (fields)&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
Table: People&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! ID&lt;br /&gt;
! First Name  &lt;br /&gt;
! Last Name&lt;br /&gt;
! Phone  &lt;br /&gt;
! Email&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Anil&lt;br /&gt;
| Somayaji&lt;br /&gt;
| 555-1212&lt;br /&gt;
| soma@scs.carleton.ca&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Dana&lt;br /&gt;
| Somayaji&lt;br /&gt;
| 555-1212&lt;br /&gt;
| dana@example.ca (should check whether it is a valid address)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Validation Problem:&lt;br /&gt;
* Where to check for bad data?&lt;br /&gt;
* Can do on:&lt;br /&gt;
** Web client (helpful)&lt;br /&gt;
** Web server (must)&lt;br /&gt;
** Database (useful)&lt;br /&gt;
&lt;br /&gt;
Example continued:&lt;br /&gt;
&lt;br /&gt;
Table: Invoices&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Inv. ID&lt;br /&gt;
! Description  &lt;br /&gt;
! Amount&lt;br /&gt;
! Customer  &lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| iPad&lt;br /&gt;
| $700&lt;br /&gt;
| 1  &amp;lt;- Which is Anil in the People table)&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| MacBookPro&lt;br /&gt;
| $1500&lt;br /&gt;
| 2 &amp;lt;- Which is Dana in the People table)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* One relation: Invoice = Customer ID -&amp;gt; People ID&lt;br /&gt;
&lt;br /&gt;
Could ask for simple queries:&lt;br /&gt;
* All records in People with first name == Anil&lt;br /&gt;
* Which customer has spent the most in our store?&lt;br /&gt;
** Sum of all invoices for each customer&lt;br /&gt;
** find max&lt;br /&gt;
&lt;br /&gt;
Indexing:&lt;br /&gt;
* Simplest: sorts specific fields in a table (create secondary keys)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Secondary key&lt;br /&gt;
! Primary key  &lt;br /&gt;
|-&lt;br /&gt;
| First Name &lt;br /&gt;
|  ID&lt;br /&gt;
|-&lt;br /&gt;
| Anil&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| Dana &lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| Annie &lt;br /&gt;
| 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* We want to sort the names Alphabetically using the secondary key.&lt;br /&gt;
&lt;br /&gt;
Transactions:&lt;br /&gt;
* What if I want to change records in multiple tables in a coordinated fashion?&lt;br /&gt;
* Airline example&lt;br /&gt;
** Reserve seat&lt;br /&gt;
** Pay&lt;br /&gt;
** Commit: check that payment and reservation both worked first&lt;br /&gt;
&lt;br /&gt;
NoSQL Databases: No transactions, no real relations&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_7&amp;diff=18822</id>
		<title>WebFund 2014W Lecture 7</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_7&amp;diff=18822"/>
		<updated>2014-03-13T17:07:32Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on January 29, 2014 is available:&lt;br /&gt;
* [http://www.screencast.com/t/5lpc5qWqGBU2 Small from screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/x2iAx5KDyj Large from screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Lecture_7_-_20140129_143752_27.mp4 Original from CUOL]&lt;br /&gt;
&lt;br /&gt;
== Databases ==&lt;br /&gt;
why?&lt;br /&gt;
* Persistence - You want to stick around (vs. RAM)&lt;br /&gt;
* Concurrency in writes - (vs. files)&lt;br /&gt;
* Search - (vs. files)&lt;br /&gt;
** Dynamic data should NOT be stored in files.&lt;br /&gt;
&lt;br /&gt;
SQL(Structured Query Language) vs. NoSQL&lt;br /&gt;
* SQL makes queries to databases, assuming queries are highly structured.&lt;br /&gt;
* for relational databases.&lt;br /&gt;
&lt;br /&gt;
What is a structure of a relational database?&lt;br /&gt;
e.g. Tables - relations connect fields between tables&lt;br /&gt;
* rows (records)&lt;br /&gt;
* columns (fields)&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
Table: People&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! ID&lt;br /&gt;
! First Name  &lt;br /&gt;
! Last Name&lt;br /&gt;
! Phone  &lt;br /&gt;
! Email&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Anil&lt;br /&gt;
| Somayaji&lt;br /&gt;
| 555-1212&lt;br /&gt;
| soma@scs.carleton.ca&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Dana&lt;br /&gt;
| Somayaji&lt;br /&gt;
| 555-1212&lt;br /&gt;
| dana@example.ca (should check whether it is a valid address)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Validation Problem:&lt;br /&gt;
* Where to check for bad data?&lt;br /&gt;
* Can do on:&lt;br /&gt;
** Web client (helpful)&lt;br /&gt;
** Web server (must)&lt;br /&gt;
** Database (useful)&lt;br /&gt;
&lt;br /&gt;
Example continued:&lt;br /&gt;
&lt;br /&gt;
Table: Invoices&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Inv. ID&lt;br /&gt;
! Description  &lt;br /&gt;
! Amount&lt;br /&gt;
! Customer  &lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| iPad&lt;br /&gt;
| $700&lt;br /&gt;
| 1  &amp;lt;- Which is Anil in the People table)&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| MacBookPro&lt;br /&gt;
| $1500&lt;br /&gt;
| 2 &amp;lt;- Which is Dana in the People table)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* One relation: Invoice = Customer ID -&amp;gt; People ID&lt;br /&gt;
&lt;br /&gt;
Could ask for simple queries:&lt;br /&gt;
* All records in People with first name == Anil&lt;br /&gt;
* Which customer has spent the most in our store?&lt;br /&gt;
** Sum of all invoices for each customer&lt;br /&gt;
** find max&lt;br /&gt;
&lt;br /&gt;
Indexing:&lt;br /&gt;
* Simplest: sorts specific fields in a table (create secondary keys)&lt;br /&gt;
&lt;br /&gt;
Secondary key           Primary key&lt;br /&gt;
========             =======&lt;br /&gt;
First Name                 ID&lt;br /&gt;
---------                 --&lt;br /&gt;
Anil                           1&lt;br /&gt;
Dana                         2&lt;br /&gt;
Annie                        3&lt;br /&gt;
&lt;br /&gt;
* sort the names Alphabetically.&lt;br /&gt;
&lt;br /&gt;
Transactions:&lt;br /&gt;
* What if I want to change records in multiple tables in a coordinated fashion?&lt;br /&gt;
* Airline example&lt;br /&gt;
** Reserve seat&lt;br /&gt;
** Pay&lt;br /&gt;
** Commit: check that payment and reservation both worked first&lt;br /&gt;
&lt;br /&gt;
NoSQL Databases: No transactions, no real relations&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_7&amp;diff=18821</id>
		<title>WebFund 2014W Lecture 7</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_7&amp;diff=18821"/>
		<updated>2014-03-13T17:04:53Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on January 29, 2014 is available:&lt;br /&gt;
* [http://www.screencast.com/t/5lpc5qWqGBU2 Small from screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/x2iAx5KDyj Large from screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Lecture_7_-_20140129_143752_27.mp4 Original from CUOL]&lt;br /&gt;
&lt;br /&gt;
== Databases ==&lt;br /&gt;
why?&lt;br /&gt;
* Persistence - You want to stick around (vs. RAM)&lt;br /&gt;
* Concurrency in writes - (vs. files)&lt;br /&gt;
* Search - (vs. files)&lt;br /&gt;
** Dynamic data should NOT be stored in files.&lt;br /&gt;
&lt;br /&gt;
SQL(Structured Query Language) vs. NoSQL&lt;br /&gt;
* SQL makes queries to databases, assuming queries are highly structured.&lt;br /&gt;
* for relational databases.&lt;br /&gt;
&lt;br /&gt;
What is a structure of a relational database?&lt;br /&gt;
e.g. Tables - relations connect fields between tables&lt;br /&gt;
* rows (records)&lt;br /&gt;
* columns (fields)&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
Table: People&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! ID&lt;br /&gt;
! First Name  &lt;br /&gt;
! Last Name&lt;br /&gt;
! Phone  &lt;br /&gt;
! Email&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Anil&lt;br /&gt;
| Somayaji&lt;br /&gt;
| 555-1212&lt;br /&gt;
| soma@scs.carleton.ca&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Dana&lt;br /&gt;
| Somayaji&lt;br /&gt;
| 555-1212&lt;br /&gt;
| dana@example.ca (should check whether it is a valid address)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Validation Problem:&lt;br /&gt;
* Where to check for bad data?&lt;br /&gt;
* Can do on:&lt;br /&gt;
** Web client (helpful)&lt;br /&gt;
** Web server (must)&lt;br /&gt;
** Database (useful)&lt;br /&gt;
&lt;br /&gt;
Example continued:&lt;br /&gt;
&lt;br /&gt;
Table: Invoices&lt;br /&gt;
&lt;br /&gt;
Inv. ID     Description      Amount      Customer&lt;br /&gt;
1             iPad                 $700          1  &amp;lt;- Which is Anil in the People table)&lt;br /&gt;
2&lt;br /&gt;
&lt;br /&gt;
* One relation: Invoice = Customer ID -&amp;gt; People ID&lt;br /&gt;
&lt;br /&gt;
Could ask for simple queries:&lt;br /&gt;
* All records in People with first name == Anil&lt;br /&gt;
* Which customer has spent the most in our store?&lt;br /&gt;
** Sum of all invoices for each customer&lt;br /&gt;
** find max&lt;br /&gt;
&lt;br /&gt;
Indexing:&lt;br /&gt;
* Simplest: sorts specific fields in a table (create secondary keys)&lt;br /&gt;
&lt;br /&gt;
Secondary key           Primary key&lt;br /&gt;
========             =======&lt;br /&gt;
First Name                 ID&lt;br /&gt;
---------                 --&lt;br /&gt;
Anil                           1&lt;br /&gt;
Dana                         2&lt;br /&gt;
Annie                        3&lt;br /&gt;
&lt;br /&gt;
* sort the names Alphabetically.&lt;br /&gt;
&lt;br /&gt;
Transactions:&lt;br /&gt;
* What if I want to change records in multiple tables in a coordinated fashion?&lt;br /&gt;
* Airline example&lt;br /&gt;
** Reserve seat&lt;br /&gt;
** Pay&lt;br /&gt;
** Commit: check that payment and reservation both worked first&lt;br /&gt;
&lt;br /&gt;
NoSQL Databases: No transactions, no real relations&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_7&amp;diff=18820</id>
		<title>WebFund 2014W Lecture 7</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_7&amp;diff=18820"/>
		<updated>2014-03-13T17:02:00Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on January 29, 2014 is available:&lt;br /&gt;
* [http://www.screencast.com/t/5lpc5qWqGBU2 Small from screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/x2iAx5KDyj Large from screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Lecture_7_-_20140129_143752_27.mp4 Original from CUOL]&lt;br /&gt;
&lt;br /&gt;
== Databases ==&lt;br /&gt;
why?&lt;br /&gt;
* Persistence - You want to stick around (vs. RAM)&lt;br /&gt;
* Concurrency in writes - (vs. files)&lt;br /&gt;
* Search - (vs. files)&lt;br /&gt;
** Dynamic data should NOT be stored in files.&lt;br /&gt;
&lt;br /&gt;
SQL(Structured Query Language) vs. NoSQL&lt;br /&gt;
* SQL makes queries to databases, assuming queries are highly structured.&lt;br /&gt;
* for relational databases.&lt;br /&gt;
&lt;br /&gt;
What is a structure of a relational database?&lt;br /&gt;
e.g. Tables - relations connect fields between tables&lt;br /&gt;
* rows (records)&lt;br /&gt;
* columns (fields)&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header 1&lt;br /&gt;
! Header 2&lt;br /&gt;
! Header 3&lt;br /&gt;
|-&lt;br /&gt;
| row 1, cell 1&lt;br /&gt;
| row 1, cell 2&lt;br /&gt;
| row 1, cell 3&lt;br /&gt;
|-&lt;br /&gt;
| row 2, cell 1&lt;br /&gt;
| row 2, cell 2&lt;br /&gt;
| row 2, cell 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Table: People&lt;br /&gt;
&lt;br /&gt;
ID     First Name      Last Name      Phone                  Email  &lt;br /&gt;
1      Anil                 Somayaji        555-1212           soma@scs.carleton.ca&lt;br /&gt;
2      Dana               Somayaji        555-1212           dana@example.ca (should check whether it is a valid address)&lt;br /&gt;
&lt;br /&gt;
Validation Problem:&lt;br /&gt;
* Where to check for bad data?&lt;br /&gt;
* Can do on:&lt;br /&gt;
** Web client (helpful)&lt;br /&gt;
** Web server (must)&lt;br /&gt;
** Database (useful)&lt;br /&gt;
&lt;br /&gt;
Example continued:&lt;br /&gt;
&lt;br /&gt;
Table: Invoices&lt;br /&gt;
&lt;br /&gt;
Inv. ID     Description      Amount      Customer&lt;br /&gt;
1             iPad                 $700          1  &amp;lt;- Which is Anil in the People table)&lt;br /&gt;
2&lt;br /&gt;
&lt;br /&gt;
* One relation: Invoice = Customer ID -&amp;gt; People ID&lt;br /&gt;
&lt;br /&gt;
Could ask for simple queries:&lt;br /&gt;
* All records in People with first name == Anil&lt;br /&gt;
* Which customer has spent the most in our store?&lt;br /&gt;
** Sum of all invoices for each customer&lt;br /&gt;
** find max&lt;br /&gt;
&lt;br /&gt;
Indexing:&lt;br /&gt;
* Simplest: sorts specific fields in a table (create secondary keys)&lt;br /&gt;
&lt;br /&gt;
Secondary key           Primary key&lt;br /&gt;
========             =======&lt;br /&gt;
First Name                 ID&lt;br /&gt;
---------                 --&lt;br /&gt;
Anil                           1&lt;br /&gt;
Dana                         2&lt;br /&gt;
Annie                        3&lt;br /&gt;
&lt;br /&gt;
* sort the names Alphabetically.&lt;br /&gt;
&lt;br /&gt;
Transactions:&lt;br /&gt;
* What if I want to change records in multiple tables in a coordinated fashion?&lt;br /&gt;
* Airline example&lt;br /&gt;
** Reserve seat&lt;br /&gt;
** Pay&lt;br /&gt;
** Commit: check that payment and reservation both worked first&lt;br /&gt;
&lt;br /&gt;
NoSQL Databases: No transactions, no real relations&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_7&amp;diff=18819</id>
		<title>WebFund 2014W Lecture 7</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_7&amp;diff=18819"/>
		<updated>2014-03-13T16:59:41Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on January 29, 2014 is available:&lt;br /&gt;
* [http://www.screencast.com/t/5lpc5qWqGBU2 Small from screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/x2iAx5KDyj Large from screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Lecture_7_-_20140129_143752_27.mp4 Original from CUOL]&lt;br /&gt;
&lt;br /&gt;
== Databases ==&lt;br /&gt;
why?&lt;br /&gt;
* Persistence - You want to stick around (vs. RAM)&lt;br /&gt;
* Concurrency in writes - (vs. files)&lt;br /&gt;
* Search - (vs. files)&lt;br /&gt;
** Dynamic data should NOT be stored in files.&lt;br /&gt;
&lt;br /&gt;
SQL(Structured Query Language) vs. NoSQL&lt;br /&gt;
* SQL makes queries to databases, assuming queries are highly structured.&lt;br /&gt;
* for relational databases.&lt;br /&gt;
&lt;br /&gt;
What is a structure of a relational database?&lt;br /&gt;
e.g. Tables - relations connect fields between tables&lt;br /&gt;
* rows (records)&lt;br /&gt;
* columns (fields)&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
Table: People&lt;br /&gt;
&lt;br /&gt;
ID     First Name      Last Name      Phone                  Email  &lt;br /&gt;
1      Anil                 Somayaji        555-1212           soma@scs.carleton.ca&lt;br /&gt;
2      Dana               Somayaji        555-1212           dana@example.ca (should check whether it is a valid address)&lt;br /&gt;
&lt;br /&gt;
Validation Problem:&lt;br /&gt;
* Where to check for bad data?&lt;br /&gt;
* Can do on:&lt;br /&gt;
** Web client (helpful)&lt;br /&gt;
** Web server (must)&lt;br /&gt;
** Database (useful)&lt;br /&gt;
&lt;br /&gt;
Example continued:&lt;br /&gt;
&lt;br /&gt;
Table: Invoices&lt;br /&gt;
&lt;br /&gt;
Inv. ID     Description      Amount      Customer&lt;br /&gt;
1             iPad                 $700          1  &amp;lt;- Which is Anil in the People table)&lt;br /&gt;
2&lt;br /&gt;
&lt;br /&gt;
* One relation: Invoice = Customer ID -&amp;gt; People ID&lt;br /&gt;
&lt;br /&gt;
Could ask for simple queries:&lt;br /&gt;
* All records in People with first name == Anil&lt;br /&gt;
* Which customer has spent the most in our store?&lt;br /&gt;
** Sum of all invoices for each customer&lt;br /&gt;
** find max&lt;br /&gt;
&lt;br /&gt;
Indexing:&lt;br /&gt;
* Simplest: sorts specific fields in a table (create secondary keys)&lt;br /&gt;
&lt;br /&gt;
Secondary key           Primary key&lt;br /&gt;
========             =======&lt;br /&gt;
First Name                 ID&lt;br /&gt;
---------                 --&lt;br /&gt;
Anil                           1&lt;br /&gt;
Dana                         2&lt;br /&gt;
Annie                        3&lt;br /&gt;
&lt;br /&gt;
* sort the names Alphabetically.&lt;br /&gt;
&lt;br /&gt;
Transactions:&lt;br /&gt;
* What if I want to change records in multiple tables in a coordinated fashion?&lt;br /&gt;
* Airline example&lt;br /&gt;
** Reserve seat&lt;br /&gt;
** Pay&lt;br /&gt;
** Commit: check that payment and reservation both worked first&lt;br /&gt;
&lt;br /&gt;
NoSQL Databases: No transactions, no real relations&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_7&amp;diff=18818</id>
		<title>WebFund 2014W Lecture 7</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=WebFund_2014W_Lecture_7&amp;diff=18818"/>
		<updated>2014-03-13T16:55:55Z</updated>

		<summary type="html">&lt;p&gt;Leah: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The video from the lecture given on January 29, 2014 is available:&lt;br /&gt;
* [http://www.screencast.com/t/5lpc5qWqGBU2 Small from screencast.com]&lt;br /&gt;
* [http://www.screencast.com/t/x2iAx5KDyj Large from screencast.com]&lt;br /&gt;
* [http://dl.cuol.ca/capture/Anil.Somayaji/COMP_2406_2014W_Lecture_7_-_20140129_143752_27.mp4 Original from CUOL]&lt;br /&gt;
&lt;br /&gt;
Databases:&lt;br /&gt;
why?&lt;br /&gt;
* Persistence - You want to stick around (vs. RAM)&lt;br /&gt;
* Concurrency in writes - (vs. files)&lt;br /&gt;
* Search - (vs. files)&lt;br /&gt;
** Dynamic data should NOT be stored in files.&lt;br /&gt;
&lt;br /&gt;
SQL(Structured Query Language) vs. NoSQL&lt;br /&gt;
* SQL makes queries to databases, assuming queries are highly structured.&lt;br /&gt;
* for relational databases.&lt;br /&gt;
&lt;br /&gt;
What is a structure of a relational database?&lt;br /&gt;
e.g. Tables - relations connect fields between tables&lt;br /&gt;
* rows (records)&lt;br /&gt;
* columns (fields)&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
=====&lt;br /&gt;
&lt;br /&gt;
Table: People&lt;br /&gt;
&lt;br /&gt;
ID     First Name      Last Name      Phone                  Email  &lt;br /&gt;
1      Anil                 Somayaji        555-1212           soma@scs.carleton.ca&lt;br /&gt;
2      Dana               Somayaji        555-1212           dana@example.ca (should check whether it is a valid address)&lt;br /&gt;
&lt;br /&gt;
Validation Problem:&lt;br /&gt;
* Where to check for bad data?&lt;br /&gt;
* Can do on:&lt;br /&gt;
** Web client (helpful)&lt;br /&gt;
** Web server (must)&lt;br /&gt;
** Database (useful)&lt;br /&gt;
&lt;br /&gt;
Example continued:&lt;br /&gt;
&lt;br /&gt;
Table: Invoices&lt;br /&gt;
&lt;br /&gt;
Inv. ID     Description      Amount      Customer&lt;br /&gt;
1             iPad                 $700          1  &amp;lt;- Which is Anil in the People table)&lt;br /&gt;
2&lt;br /&gt;
&lt;br /&gt;
* One relation: Invoice = Customer ID -&amp;gt; People ID&lt;br /&gt;
&lt;br /&gt;
Could ask for simple queries:&lt;br /&gt;
* All records in People with first name == Anil&lt;br /&gt;
* Which customer has spent the most in our store?&lt;br /&gt;
** Sum of all invoices for each customer&lt;br /&gt;
** find max&lt;br /&gt;
&lt;br /&gt;
Indexing:&lt;br /&gt;
* Simplest: sorts specific fields in a table (create secondary keys)&lt;br /&gt;
&lt;br /&gt;
                          Secondary key           Primary key&lt;br /&gt;
                          ========             =======&lt;br /&gt;
                           First Name                 ID&lt;br /&gt;
                           ---------                 --&lt;br /&gt;
&amp;gt;&amp;gt;                      Anil                           1&lt;br /&gt;
sort                     Dana                         2&lt;br /&gt;
these                   Annie                        3&lt;br /&gt;
alphabetically&lt;br /&gt;
&lt;br /&gt;
Transactions:&lt;br /&gt;
* What if I want to change records in multiple tables in a coordinated fashion?&lt;br /&gt;
* Airline example&lt;br /&gt;
** Reserve seat&lt;br /&gt;
** Pay&lt;br /&gt;
** Commit: check that payment and reservation both worked first&lt;br /&gt;
&lt;br /&gt;
NoSQL Databases: No transactions, no real relations&lt;/div&gt;</summary>
		<author><name>Leah</name></author>
	</entry>
</feed>