diff options
| author | wei <> | 2006-07-14 06:46:31 +0000 | 
|---|---|---|
| committer | wei <> | 2006-07-14 06:46:31 +0000 | 
| commit | c004bbdf4f0e824e5ccbaef8f98ca4a3d44d3b49 (patch) | |
| tree | 9bbf7122021251617c4fba1163eaa5ee222c57d7 /demos/sqlmap-docs/protected/pages/Tutorial | |
| parent | 61bb16ee2e5f0a66234e1575242169a10fde47b5 (diff) | |
Changed SQLMap manual into a prado app.
Diffstat (limited to 'demos/sqlmap-docs/protected/pages/Tutorial')
| -rw-r--r-- | demos/sqlmap-docs/protected/pages/Tutorial/TestAgain.page | 214 | ||||
| -rw-r--r-- | demos/sqlmap-docs/protected/pages/Tutorial/TestFirst.page | 238 | ||||
| -rw-r--r-- | demos/sqlmap-docs/protected/pages/Tutorial/TestSecond.page | 116 | ||||
| -rw-r--r-- | demos/sqlmap-docs/protected/pages/Tutorial/example1.png | bin | 0 -> 236887 bytes | |||
| -rw-r--r-- | demos/sqlmap-docs/protected/pages/Tutorial/grid1.png | bin | 0 -> 275250 bytes | |||
| -rw-r--r-- | demos/sqlmap-docs/protected/pages/Tutorial/grid2.png | bin | 0 -> 218210 bytes | 
6 files changed, 568 insertions, 0 deletions
| diff --git a/demos/sqlmap-docs/protected/pages/Tutorial/TestAgain.page b/demos/sqlmap-docs/protected/pages/Tutorial/TestAgain.page new file mode 100644 index 00000000..4adac73b --- /dev/null +++ b/demos/sqlmap-docs/protected/pages/Tutorial/TestAgain.page @@ -0,0 +1,214 @@ +<com:TContent ID="body">
 +<h1>Test, test, again ...</h1>
 +<p>Of course, tweaking the Person List display is not going to be the end of it.
 +Clients always want more, and now ours wants to edit, add, or delete records.
 +Let's write some tests for these new tasks, as shown in the following.</p>
 +
 +<com:TTextHighlighter Language="php" CssClass="source">
 +function testPersonUpdate()
 +{
 +	$expect = "wei";
 +	$edited = "Nah";
 +
 +	//get it;
 +	$person = TMapper::instance()->queryForObject("Select", 1);
 +
 +	//test it
 +	$this->assertNotNull($person);
 +	$this->assertEqual($expect, $person->FirstName);
 +
 +	//change it
 +	$person->FirstName = $edited;
 +	TMapper::instance()->update("Update", $person);
 +
 +	//get it again
 +	$person = TMapper::instance()->queryForObject("Select", 1);
 +
 +	//test it
 +	$this->assertEqual($edited, $person->FirstName);
 +
 +	//change it back
 +	$person->FirstName = $expect;
 +	TMapper::instance()->update("Update", $person);
 +}
 +
 +function testPersonDelete()
 +{
 +	//insert it
 +	$person = new Person;
 +	$person->ID = -1;
 +	TMapper::instance()->insert("Insert", $person);
 +
 +	//delte it
 +	$count = TMapper::instance()->delete("Delete", -1);
 +	$this->assertEqual(1, $count);
 +}
 +</com:TTextHighlighter>
 +
 +<p>Not the best tests ever written, but for now, they will do :)</p>
 +
 +<p>To make the new tests work, we'll need some new mapping statements.
 +The following sample shows the complete mapper document that we've called
 +<tt>personHelper.xml</tt>.</p>
 +
 +<com:TTextHighlighter Language="xml" CssClass="source">
 +<?xml version="1.0" encoding="utf-8" ?>
 +
 +<sqlMap Name="PersonHelper">
 +  <select id="Select" parameterClass="int" resultClass="Person">
 +   select
 +    PER_ID as ID,
 +    PER_FIRST_NAME as FirstName,
 +    PER_LAST_NAME as LastName,
 +    PER_BIRTH_DATE as BirthDate,
 +    PER_WEIGHT_KG as WeightInKilograms,
 +    PER_HEIGHT_M as HeightInMeters
 +    from PERSON
 +    WHERE
 +      PER_ID = #value#
 +  </select>
 +
 +  <insert id="Insert" parameterClass="Person">
 +   insert into PERSON
 +    (PER_ID, PER_FIRST_NAME, PER_LAST_NAME,
 +    PER_BIRTH_DATE, PER_WEIGHT_KG, PER_HEIGHT_M)
 +   values
 +    (#ID#, #FirstName#, #LastName#,
 +    #BirthDate#, #WeightInKilograms#, #HeightInMeters#)
 +  </insert>
 +
 +  <update id="Update" parameterClass="Person">
 +   update PERSON set
 +    PER_FIRST_NAME = #FirstName#,
 +    PER_LAST_NAME = #LastName#,
 +    PER_BIRTH_DATE = #BirthDate#,
 +    PER_WEIGHT_KG = #WeightInKilograms#,
 +    PER_HEIGHT_M = #HeightInMeters#
 +   where PER_ID = #ID#
 +  </update>
 +
 +  <delete id="Delete" parameterClass="int">
 +   delete from PERSON
 +   where PER_ID = #value#
 +  </delete>
 +</sqlMap>
 +</com:TTextHighlighter>
 +
 +<p>Well, waddya know, if run our tests now, we are favored with a green bar!. It
 +all works!</p>
 +
 +<div class="note"><b class="tip">Note:</b>
 +Though, of course, things usually do not work perfectly the first time! We
 +have to fix this and that, and try, try, again. But SimpleTest makes trying
 +again quick and easy. You can changes to the XML mapping documents and rerun
 +the tests! No muss, no fuss.
 +</div>
 +
 +<p>Turning back to our Prado page, we can revamp the <tt>TDataGrid</tt> to allow in-place
 +editing and deleting. To add records, we provide a button after the grid that
 +inserts a blank person for client to edit. The page code is shown as:
 +
 +<com:TTextHighlighter Language="prado" CssClass="source">
 +    <com:TDataGrid id="personList"
 +            DataKeyField="ID"
 +            AutoGenerateColumns="False"
 +            OnEditCommand="editPerson"
 +            OnUpdateCommand="updatePerson"
 +            OnCancelCommand="refreshList"
 +            OnDeleteCommand="deletePerson">
 +        <com:TBoundColumn DataField="FirstName" HeaderText="First Name" />
 +        <com:TBoundColumn DataField="LastName" HeaderText="Last Name" />
 +        <com:TBoundColumn DataField="HeightInMeters" HeaderText="Height" />
 +        <com:TBoundColumn DataField="WeightInKilograms" HeaderText="Weight" />
 +        <com:TEditCommandColumn
 +                HeaderText="Edit"
 +                UpdateText="Save" />
 +        <com:TButtonColumn
 +                HeaderText="Delete"
 +                Text="Delete"
 +                CommandName="delete"/>
 +    </com:TDataGrid>
 +    <com:TButton Text="Add" OnClick="addNewPerson" />
 +</com:TTextHighlighter>
 +
 +<p>The following sample shows the corresponding methods from page PHP class.</p>
 +
 +<com:TTextHighlighter Language="php" CssClass="source">
 +    private function sqlmap()
 +    {
 +        return $this->Application->getModule('SQLMap')->getClient();
 +    }
 +
 +    private function loadData()
 +    {
 +        $this->personList->DataSource =
 +                $this->sqlmap()->queryForList('SelectAll');
 +        $this->personList->dataBind();
 +    }
 +
 +    public function onLoad($param)
 +    {
 +        if(!$this->IsPostBack)
 +            $this->loadData();
 +    }
 +
 +    protected function editPerson($sender,$param)
 +    {
 +        $this->personList->EditItemIndex=$param->Item->ItemIndex;
 +        $this->loadData();
 +    }
 +
 +    protected function deletePerson($sender, $param)
 +    {
 +        $id = $this->getKey($sender, $param);
 +        $this->sqlmap()->update("Delete", $id);
 +        $this->loadData();
 +    }
 +
 +    protected function updatePerson($sender, $param)
 +    {
 +        $person = new Person();
 +        $person->FirstName = $this->getText($param, 0);
 +        $person->LastName = $this->getText($param, 1);
 +        $person->HeightInMeters = $this->getText($param, 2);
 +        $person->WeightInKilograms = $this->getText($param, 3);
 +        $person->ID = $this->getKey($sender, $param);
 +        $this->sqlmap()->update("Update", $person);
 +        $this->refreshList($sender, $param);
 +    }
 +
 +    protected function addNewPerson($sender, $param)
 +    {
 +        $person = new Person;
 +        $person->FirstName = "-- New Person --";
 +        $this->sqlmap()->insert("Insert", $person);
 +        $this->loadData();;
 +    }
 +
 +    protected function refreshList($sender, $param)
 +    {
 +        $this->personList->EditItemIndex=-1;
 +        $this->loadData();
 +    }
 +
 +    private function getText($param, $index)
 +    {
 +        $item = $param->Item;
 +        return $item->Cells[$index]->Controls[0]->Text;
 +    }
 +
 +    private function getKey($sender, $param)
 +    {
 +        return $sender->DataKeys[$param->Item->DataSourceIndex];
 +    }
 +</com:TTextHighlighter>
 +
 +<p>OK, we are CRUD complete! There's more we could do here. In particular, we
 +should add validation methods to prevent client from entering alphabetic
 +characters where only numbers can live. But, that's a different Prado
 +tutorial, and this is an SQLMap DataMapper tutorial.</p>
 +
 +<img src=<%~ grid2.png %> class="figure" />
 +<div class="caption"><b>Figure 4:</b> Person List CRUD</div>
 +
 +</com:TContent>
\ No newline at end of file diff --git a/demos/sqlmap-docs/protected/pages/Tutorial/TestFirst.page b/demos/sqlmap-docs/protected/pages/Tutorial/TestFirst.page new file mode 100644 index 00000000..80a155cb --- /dev/null +++ b/demos/sqlmap-docs/protected/pages/Tutorial/TestFirst.page @@ -0,0 +1,238 @@ +<com:TContent ID="body">
 +<h1>Test First!</h1>
 +
 +<p>Let's say that our most important client has a database and one of the tables
 +in the database is a list of people. Our client tells us:</p>
 +
 +<p>"We would like to use a web application to display the people in this table
 +and to add, edit, and delete individual records."</p>
 +
 +<p>Not a complicated story, but it will cover the CRUD most developers want to
 +learn first. :) Let's start with the people table that the client mentioned.
 +Since we're keeping it simple, we'll say it's a table in an Access database.
 +The table definition is shown as:</p>
 +
 +<com:TTextHighlighter Language="sql" CssClass="source">
 +Name              Type            Size
 +PER_ID            Long Integer      4
 +PER_FIRST_NAME    Text             40
 +PER_LAST_NAME     Text             40
 +PER_BIRTH_DATE    Date/Time         8
 +PER_WEIGHT_KG     Double            8
 +PER_HEIGHT_M      Double            8
 +</com:TTextHighlighter>
 +
 +<div class="tip"><b class="tip">Tip:</b>
 +    This example is bundled with a SQLite database file "Data/test.db"
 +    that contains the <tt>Person</tt> table and some data, ready to use.
 +</div>
 +
 +<p>The first thing our story says is that client would like to display a list of
 +people. The following example shows our test for that.</p>
 +
 +<com:TTextHighlighter Language="php" CssClass="source">
 +<?php
 +class PersonTest extends UnitTestCase
 +{
 +    function testPersonList()
 +    {
 +        //try it
 +        $people = TMapper::instance()->queryForList("SelectAll");
 +
 +        //test it
 +        $this->assertNotNull($people, "Person list is not returned");
 +        $this->assertTrue($people->getCount() > 0, "Person list is empty");
 +        $person = $people[0];
 +        $this->assertNotNull($person, "Person not returned");
 +    }
 +}
 +?>
 +</com:TTextHighlighter>
 +
 +<p>Well, the example sure looks easy enough! We ask a method to "select all", and
 +it returns a list of person objects. But, what code do we need to write to
 +pass this test?</p>
 +
 +<div class="note"><b class="tip">Note:</b>
 +    Save the <tt>PersonTest.php</tt> into a <tt>tests</tt> directory. 
 +    The unit tests are written for the <a href="http://simpletest.sf.net">SimpleTest Unit Testing framework</a>.
 +</div>
 +
 +<p>Now, to setup the testing framework, suppose you have the <tt>SimpleTest</tt>
 +framework installed. Then we need to create an entry file to run the tests.
 +See the <tt>SimpleTest</tt> documentation for further details on setting up tests.</p>
 +
 +<com:TTextHighlighter Language="php" CssClass="source">
 +<?php
 +require_once('../tests/simpletest/unit_tester.php');
 +require_once('../tests/simpletest/reporter.php');
 +require_once('../SQLMap/TMapper.php');
 +require_once('Models/Person.php');
 +
 +//supress strict warnings from Adodb.
 +error_reporting(E_ALL);
 +
 +$test = new GroupTest('All tests');
 +$test->addTestFile('Tests/PersonTest.php'); $test->run(new HtmlReporter());
 +?>
 +</com:TTextHighlighter>
 +
 +<p>To run the tests, point your browser to the "<tt>run_test.php</tt>" script file
 +served from your web server.</p>
 +
 +<p>Let's see. The test uses a list of person objects. We could start with a blank
 +object, just to satisfy the test, and add the display properties later. But
 +let's be naughty and skip a step. Our fully-formed person object is shown in
 +the following example</p>
 +
 +<com:TTextHighlighter Language="php" CssClass="source">
 +<?php
 +class Person
 +{
 +    public $ID = -1;
 +    public $FirstName;
 +    public $LastName;
 +    public $WeightInKilograms = 0.0;
 +    public $HeightInMeters = 0.0;
 +
 +    private $_birthDate;
 +
 +    //setters and getter for BirthDate
 +    public function getBirthDate()
 +    {
 +        return $this->_birthDate;
 +    }
 +
 +    public function setBirthDate($value)
 +    {
 +        $this->_birthDate = $value;
 +    }
 +}
 +?>
 +</com:TTextHighlighter>
 +
 +<p>OK, that was fun! The <tt>$this->assertXXX(...)</tt> methods are built into
 +<tt>UnitTestCase</tt> class. So to run the unit test example, we just need the
 +<tt>TMapper</tt> object and <tt>queryForList</tt> method. Wonderfully, the SQLMap
 +DataMapper framework has a <tt>TMapper</tt>class built into it that will work just
 +fine for for us to use in this tutorial, so we don't need to write that
 +either.</p>
 +
 +<p>When the <tt>TMapper->instance()</tt> method is called, an instance of the SQLMap
 +<tt>TSqlMapper</tt> class is returned that has various methods available such as
 +<tt>queryForList</tt>. In this example, the SQLMap <tt>TSqlMapper->queryForList()</tt>
 +method executes our SQL statement (or stored procedure) and returns the result
 +as a list. Each row in the result becomes an entry in the list. Along with
 +<tt>queryForList()</tt>, there are also <tt>delete()</tt>, <tt>insert()</tt>,
 +<tt>queryForObject()</tt>, <tt>queryForPagedList()</tt> and a few other methods in the
 +<a href="?page=Manual.DataMapperAPI">SQLMap API</a>. 
 +
 +<p>Looking at unit test example, we see that the <tt>queryForList()</tt> method
 +takes the name of the statement we want to run. OK. Easy enough. But where
 +does SQLMap get the "SelectAll" statement? Some systems try to generate SQL
 +statements for you, but SQLMap specializes in data mapping, not code
 +generation. It's our job (or the job of our database administrator) to craft
 +the SQL or provide a stored procedure. We then describe the statement in an
 +XML element, like the one shown the following where
 +we use XML elements to map a database statement to an application object.
 +
 +<com:TTextHighlighter Language="xml" CssClass="source">
 +<?xml version="1.0" encoding="utf-8" ?>
 +<sqlMap>
 +    <select id="SelectAll" resultClass="Person">
 +        SELECT
 +            per_id as ID,
 +            per_first_name as FirstName,
 +            per_last_name as LastName,
 +            per_birth_date as BirthDate,
 +            per_weight_kg as WeightInKilograms,
 +            per_height_m as HeightInMeters
 +        FROM
 +            person
 +    </select>
 +</sqlMap>
 +</com:TTextHighlighter>
 +
 +<p>The SQLMap mapping documents can hold several sets of related elements, like
 +those shown in the unit test case example. We can also have as many mapping
 +documents as we need to help organize our code. Additionally, having multiple
 +mapping documents is handy when several developers are working on the project
 +at once.</p>
 +
 +<p>So, the framework gets the SQL code for the query from the mapping, and plugs
 +it into a prepared statement. But, how does SQLMap know where to find the
 +table's datasource?</p>
 +
 +<p>Surprise! More XML! You can define a configuration file for each datasource
 +your application uses. The following code shows a configuration file named "<tt>sqlmap.config</tt>" for
 +our SQLite database.</p>
 +
 +<com:TTextHighlighter Language="xml" CssClass="source">
 +<?xml version="1.0" encoding="UTF-8" ?>
 +<sqlMapConfig>
 +    <provider class="TAdodbProvider">
 +        <datasource driver="sqlite" host="Data/test.db" />
 +    </provider>
 +    <sqlMaps>
 +        <sqlMap resource="Data/person.xml"/>
 +    </sqlMaps>
 +</sqlMapConfig>
 +</com:TTextHighlighter>
 +
 +<p>The <tt><provider></tt> specifies the database provider class, in this case
 +<tt>TAdodbProvider</tt> using the Adodb library. The <tt><datasource></tt> tag
 +specifies the database connection details. In this case, for an SQLite
 +database, we just need the driver name, and the host that points to the actual
 +SQLite database file.</p>
 +
 +<p>The last part of the configuration file ("sqlMaps") is where we list our
 +mapping documents, like the one shown back in the previous code sample. We can
 +list as many documents as we need here, and they will all be read when the
 +configuration is parsed.</p>
 +
 +<p>OK, so how does the configuration get parsed?</p>
 +
 +<p>Look back at the unit test case example. The heart of the code is the call to the
 +"<tt>TMapper</tt>" object (under the remark "try it"). The <tt>TMapper</tt> object
 +is a singleton that handles the instantiation and configuration of an SQLMap
 +<tt>TSqlMapper</tt> object, which provides a facade to the SQLMap DataMapper
 +framework API.</p>
 +
 +<p>The first time that the <tt>TMapper</tt> is called, it reads in the
 +<tt>sqlmap.config</tt> file and associated mapping documents to create an instance
 +of the <tt>TSqlMapper</tt> class. On subsequent calls, it reuses the
 +<tt>TSqlMapper</tt> object so that the configuration is not re-read.</p>
 +
 +<p>The framework comes bundled with a default <tt>TMapper</tt> class for you to use
 +immediately to get access to the SQLMap client <tt>TSqlMapper</tt> object. If you want to use a
 +different name other than <tt>sqlmap.config</tt> at the default location for the
 +configuration file, or need to use more than one database and have one
 +TSqlMapper per database, you can also write your own class to mimic the role of
 +the Mapper class view by copying and modifying the standard version.</p>
 +
 +<div class="tip"><b class="tip">Tip:</b>
 +    You can also call <tt>TMapper::configure('/path/to/your/sqlmap.config')</tt>
 +    to configure the <tt>TMapper</tt> for a specific configuration file.
 +</div>
 +
 +<p>If we put this all together into a solution, we can "green bar" our test. At
 +this point you should have the following files.</p>
 +<com:TTextHighlighter Language="code" CssClass="source">
 +Data/person.xml             % Mapping file.
 +Data/test.db                % SQLite database file.
 +
 +Models/Person.php           % Person class file.
 +
 +Tests/PersonTest.php        % Unit test case for Person mapping.
 +
 +run_tests.php               % Unit test entry point.
 +sqlmap.config               % SQLMap configuration file.
 +</com:TTextHighlighter>
 +
 +<p>Run the tests by pointing your browser URL to the "<tt>run_tests.php</tt>" server
 +file.</p>
 +
 +<img src=<%~ example1.png %> class="figure" />
 +<div class="caption"><b>Figure 2:</b> Green Bar!</div>
 +
 +</com:TContent>
\ No newline at end of file diff --git a/demos/sqlmap-docs/protected/pages/Tutorial/TestSecond.page b/demos/sqlmap-docs/protected/pages/Tutorial/TestSecond.page new file mode 100644 index 00000000..706b5220 --- /dev/null +++ b/demos/sqlmap-docs/protected/pages/Tutorial/TestSecond.page @@ -0,0 +1,116 @@ +<com:TContent ID="body">
 +
 +<h1>Playtest second!</h1>
 +<p>Now that we have a passing test, we want to display some results as web pages.
 +The following examples utilize the Prado framework to display and manipulate
 +the database through SQLMap. Since SQLMap framework and Prado framework solve
 +different problems, they are both fairly independent, they can be used
 +together or separately.</p>
 +
 +<h2>SQLMap and Prado</h2>
 +<p>To setup Prado, we need to create the follow files and directory structure
 +under our <tt>example/WebView</tt> directory.</p>
 +<com:TTextHighlighter Language="code" CssClass="source">
 +assets/                         % application public assets
 +
 +protected/pages/Home.page       % default page
 +protected/pages/Home.php        % default page class
 +protected/runtime/              % run time data
 +
 +protected/application.xml       % application configuration
 +
 +index.php                       % application entry point
 +</com:TTextHighlighter>
 +
 +<p>The <tt>application.xml</tt> and <tt>assets</tt> directory are not necessary but we
 +will make use of them later. The <tt>application.xml</tt> is used to define some
 +directory aliases and override the data source definitions in the
 +<tt>sqlmap.config</tt>. This is because SQLite database files are defined
 +relatively, otherwise we don't need to override the data source definitions.
 +The example <tt>application.xml</tt> is shown below, defining path aliases and override SQLite database
 +location.</p>
 +
 +<com:TTextHighlighter Language="xml" CssClass="source">
 +<?xml version="1.0" encoding="utf-8"?>
 +<application id="SQLMap Example" Mode="Debug">
 +  <paths>
 +    <alias id="Example" path="../../" />
 +    <using namespace="System.DataAccess.*" />
 +  </paths>
 +  <modules>
 +    <module id="SQLMap" class="TSQLMap"
 +            configFile="Example.sqlmap">
 +        <!-- override sqlmap.config's database provider -->
 +        <provider class="TAdodbProvider">
 +            <datasource driver="sqlite" host="../Data/test.db" />
 +        </provider>
 +    </module>
 +  </modules>
 +</application>
 +</com:TTextHighlighter>
 +
 +<p>The entry point to a Prado application in this example is <tt>index.php</tt>
 +and generally contains the following code.</p>
 +
 +<com:TTextHighlighter Language="php" CssClass="source">
 +<?php
 +error_reporting(E_ALL);
 +require_once('/path/to/prado/framework/prado.php');
 +$application=new TApplication;
 +$application->run();
 +?>
 +</com:TTextHighlighter>
 +
 +<p>Now we are ready to setup a page to display our list of people.
 +The following sample shows the Prado code for our display page. The key
 +piece is the <tt>TDataGrid</tt>. We save the file as <tt>Home.page</tt>.</p>
 +
 +<com:TTextHighlighter Language="prado" CssClass="source">
 +<!doctype html public "-//W3C//DTD XHTML 1.0 Strict//EN"
 +    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 +<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
 +<head>
 +    <title>Person</title>
 +</head>
 +<body>
 +<com:TForm>
 +    <h1>Person List</h1>
 +    <com:TDataGrid id="personList">
 +        <com:TBoundColumn DataField="BirthDate"
 +                HeaderText="Birth Date"/>
 +    </com:TDataGrid>
 +</com:TForm>
 +</body>
 +</html>
 +</com:TTextHighlighter>
 +
 +<p>Of course, we still need to populate that TDataGrid. The following code
 +shows the PHP for <tt>Home.php</tt>. The operative method is <tt>loadData()</tt>.
 +The rest is supporting code.</p>
 +
 +<com:TTextHighlighter Language="php" CssClass="source">
 +<?php
 +Prado::using('Example.Models.Person');
 +class Home extends TPage
 +{
 +    private function loadData()
 +    {
 +        $sqlmap = $this->Application->getModule('SQLMap')->getClient();
 +        $this->personList->DataSource = $sqlmap->queryForList('SelectAll');
 +        $this->personList->dataBind();
 +    }
 +
 +    public function onLoad($param)
 +    {
 +        if(!$this->IsPostBack)
 +            $this->loadData();
 +    }
 +}
 +?>
 +</com:TTextHighlighter>
 +
 +<p>If we run this now, we'll get a list like the one shown the figure below.</p>
 +<img src=<%~ grid1.png %> class="figure" />
 +<div class="caption"><b>Figure 3:</b> A quick-and-dirty Person List</div>
 +
 +</com:TContent>
\ No newline at end of file diff --git a/demos/sqlmap-docs/protected/pages/Tutorial/example1.png b/demos/sqlmap-docs/protected/pages/Tutorial/example1.pngBinary files differ new file mode 100644 index 00000000..b5241de6 --- /dev/null +++ b/demos/sqlmap-docs/protected/pages/Tutorial/example1.png diff --git a/demos/sqlmap-docs/protected/pages/Tutorial/grid1.png b/demos/sqlmap-docs/protected/pages/Tutorial/grid1.pngBinary files differ new file mode 100644 index 00000000..845b9581 --- /dev/null +++ b/demos/sqlmap-docs/protected/pages/Tutorial/grid1.png diff --git a/demos/sqlmap-docs/protected/pages/Tutorial/grid2.png b/demos/sqlmap-docs/protected/pages/Tutorial/grid2.pngBinary files differ new file mode 100644 index 00000000..dcafc33d --- /dev/null +++ b/demos/sqlmap-docs/protected/pages/Tutorial/grid2.png | 
