Author: ianb
Date: 2004-11-11 09:33:25 -0500 (Thu, 11 Nov 2004)
New Revision: 349
Added:
trunk/SQLObject/docs/presentation-2004-11/
trunk/SQLObject/docs/presentation-2004-11/sqlobject-and-database-progr=
amming.html
trunk/SQLObject/docs/presentation-2004-11/ui/
trunk/SQLObject/docs/presentation-2004-11/ui/bodybg.gif
trunk/SQLObject/docs/presentation-2004-11/ui/custom.css
trunk/SQLObject/docs/presentation-2004-11/ui/framing.css
trunk/SQLObject/docs/presentation-2004-11/ui/opera.css
trunk/SQLObject/docs/presentation-2004-11/ui/pretty.css
trunk/SQLObject/docs/presentation-2004-11/ui/print.css
trunk/SQLObject/docs/presentation-2004-11/ui/s5-core.css
trunk/SQLObject/docs/presentation-2004-11/ui/slides.css
trunk/SQLObject/docs/presentation-2004-11/ui/slides.js
Log:
A presentation I'm giving
Added: trunk/SQLObject/docs/presentation-2004-11/sqlobject-and-database-p=
rogramming.html
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/SQLObject/docs/presentation-2004-11/sqlobject-and-database-prog=
ramming.html 2004-11-11 14:12:55 UTC (rev 348)
+++ trunk/SQLObject/docs/presentation-2004-11/sqlobject-and-database-prog=
ramming.html 2004-11-11 14:33:25 UTC (rev 349)
@@ -0,0 +1,769 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"=20
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns=3D"http://www.w3.org/1999/xhtml">
+
+<head>
+<title>SQLObject and Database Programming in Python</title>
+<meta name=3D"version" content=3D"S5 1.0" />
+<link rel=3D"stylesheet" href=3D"ui/slides.css" type=3D"text/css" media=3D=
"projection" id=3D"slideProj" />
+<link rel=3D"stylesheet" href=3D"ui/opera.css" type=3D"text/css" media=3D=
"projection" id=3D"operaFix" />
+<link rel=3D"stylesheet" href=3D"ui/print.css" type=3D"text/css"
+media=3D"print" id=3D"slidePrint" />
+<link rel=3D"stylesheet" href=3D"ui/custom.css" type=3D"text/css"/>
+<sc ript src=3D"ui/slides.js" type=3D"text/javascript"></script>
+</head>
+<body>
+
+<div class=3D"layout">
+
+<div id=3D"currentSlide"></div>
+<div id=3D"header"></div>
+<div id=3D"footer">
+<h1>ChiPy, 11 November 2004</h1>
+<h2>SQLObject and Database Programming in Python</h2>
+<div id=3D"controls"></div>
+</div>
+
+</div>
+
+
+<div class=3D"presentation">
+
+<div class=3D"slide">
+<h1>SQLObject and Database Programming in Python</h1>
+<h3>Ian Bicking</h3>
+<h4>Imaginary Landscape</h4>
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+<div class=3D"slide">
+<h1>The Ongoing Example</h1>
+
+<h2>Address book:</h2>
+<p>
+<ul>
+ <li><code>person</code>:
+ <ul>
+ <li><code>first_name</code></li>
+ <li><code>last_name</code></li>
+ <li><code>email</code> (many emails for one person)</li>
+ </ul></li>
+ <li><code>email</code>:
+ <ul>
+ <li><code>type</code></li>
+ <li><code>address</code></li>
+ </ul></li>
+</ul>
+</p>
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+<div class=3D"slide">
+<h1>Database Programming in Python</h1>
+
+<p>Database programming in Python is based on the <b><a
+href=3D"http://www.python.org/peps/pep-0249.html">DB-API</a></b>.
+Some supported databases:
+
+<ul>
+<li>MySQL</li>
+<li>PostgreSQL (multiple drivers)</li>
+<li>SQLite</li>
+<li>Oracle</li>
+<li>Sybase</li>
+<li>Firebird (Interbase)</li>
+<li>MAXDB (SAP DB)</li>
+<li>MS SQL Server</li>
+</p>
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+<div class=3D"slide">
+<h1>DB API Example</h1>
+
+<p>
+Example:
+
+<pre>
+import MySQLdb
+conn =3D MySQLdb.connect(
+ db=3D<span class=3D"string">'test'</span>, username=3D<span class=3D=
"string">'ianb'</span>)
+cur =3D conn.cursor()
+cur.execute(
+ <span class=3D"sql">"SELECT id, first_name, last_name FROM person"</=
span>)
+result =3D cur.fetchall()
+for id, first_name, last_name in result:
+ print <span class=3D"string">"%2i %s, %s"</span> % (id, last_name, f=
irst_name)
+</pre>
+
+</p>
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+<div class=3D"slide">
+<h1>DB API</h1>
+
+<ul>
+<li> Import the databse module (<code>MySQLdb</code>,
+<code>psycopg</code>, <code>sqlite</code>, etc) </li>
+<li> Use <code>module.connect(...)</code> to create a
+connection. </li>
+<li> Use <code>connection.cursor()</code> to get a cursor. Cursors do
+all the work. </li>
+<li> Use <code>cursor.execute(sql_query)</code> to run
+something. </li>
+<li> Use <code>cursor.fetchall()</code> to get results. </li>=20
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+<div class=3D"slide">
+<h1>DB API problems</h1>
+
+<ol>
+<li> Connections and cursors are tedious. </li>
+<li> The databases don't all work the same; multiple SQL
+dialects. </li>
+<li> Lots of time spent writing SQL. </li>
+<li> Database updates can effect all the SQL you've written. </li>
+<li> Unless you make abstractions... </li>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+<div class=3D"slide">
+<h1>Abstractions</h1>
+
+<p>
+<ul>
+<li> Every significant database application has a database abstraction
+layer. </li>
+<li> You write one whether you mean to or not. </li>
+</p>
+
+</div>
+
+
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+<div class=3D"slide">
+<h1>Object-Relational Mappers</h1>
+
+<p>
+
+The table:
+
+<table border=3D1>
+
+<tr><th colspan=3D3>person</th></tr>
+
+<tr>
+ <th>id</th>
+ <th>first_name</th>
+ <th>last_name</th>
+</tr>
+
+<tr>
+ <td>1</td>
+ <td>John</td>
+ <td>Doe</td>
+</tr>
+<tr>
+ <td>2</td>
+ <td>Tom</td>
+ <td>Jones</td>
+</tr>
+<tr>
+ <td colspan=3D3 align=3Dcenter>...</td>
+</tr>
+</table>
+
+<p>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+<div class=3D"slide">
+
+<h1>Object-Relational Mappers: Classes</h1>
+
+<p>
+
+The class:
+
+<table border=3D1>
+
+<tr class=3D"code-accent"><th colspan=3D3>person</th></tr>
+
+<tr class=3D"code-accent">
+ <th>id</th>
+ <th>first_name</th>
+ <th>last_name</th>
+</tr>
+
+<tr>
+ <td>1</td>
+ <td>John</td>
+ <td>Doe</td>
+</tr>
+<tr>
+ <td>2</td>
+ <td>Tom</td>
+ <td>Jones</td>
+</tr>
+<tr>
+ <td colspan=3D3 align=3Dcenter>...</td>
+</tr>
+
+</table>
+<p>
+
+<pre>
+class Person(SQLObject):
+ <span class=3D"comment"># id is implicit</span>
+ first_name =3D StringCol()
+ last_name =3D StringCol()
+</pre>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+
+<h1>Object-Relational Mappers: Instances</h1>
+
+<p>
+
+An instance:
+
+<table border=3D1>
+
+<tr><th colspan=3D3>person</th></tr>
+
+<tr>
+ <th>id</th>
+ <th>first_name</th>
+ <th>last_name</th>
+</tr>
+
+<tr class=3D"code-accent">
+ <td>1</td>
+ <td>John</td>
+ <td>Doe</td>
+</tr>
+<tr>
+ <td>2</td>
+ <td>Tom</td>
+ <td>Jones</td>
+</tr>
+<tr>
+ <td colspan=3D3 align=3Dcenter>...</td>
+</tr>
+
+</table>
+<p>
+
+<pre>
+john =3D Person.get(1)
+assert john.first_name =3D=3D <span class=3D"string">'John'</span>
+</pre>
+
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>Object-Relational Mapping: summary</h1>
+
+<ul>
+ <li>Every table is a class</li>
+ <li>Every row is an instance</li>
+ <li>Columns become attributes</li>
+</ul>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>Usage</h1>
+
+<pre>
+__connection__ =3D <span class=3D"string">'postgres://pgsql@localhost/te=
st'</span>
+class Person(SQLObject):
+ first_name =3D StringCol()
+ last_name =3D StringCol()
+ emails =3D MultipleJoin('Email')
+class Email(SQLObject):
+ person =3D ForeignKey(<span class=3D"string">'Person'</span>)
+ type =3D EnumCol(['home', 'work'])
+ address =3D StringCol()
+def createTables():
+ for table in (Person, Email):
+ table.createTable(ifNotExists=3DTrue)
+</pre>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+<div class=3D"slide">
+<h1>More use...</h1>
+
+Using your classes:
+
+<pre>
+<span class=3D"prompt">>>></span> john =3D Person(first_name=3D=
<span class=3D"string">'John'</span>, last_name=3D<span class=3D"string">=
'Doe'</span>)
+<span class=3D"prompt">>>></span> email =3D Email(person=3Djohn=
, type=3D<span class=3D"string">'home'</span>,=20
+<span class=3D"prompt">...</span> address=3D<span class=3D"string">'=
jo...@wo...'</span>)
+<span class=3D"prompt">>>></span> john.emails
+<span class=3D"output">[]</span>
+<span class=3D"prompt">>>></span> tom =3D Person(first_name=3D<=
span class=3D"string">'Tom'</span>, last_name=3D<span class=3D"string">'J=
ones'</span>)
+<span class=3D"prompt">>>></span> tom is Person.get(tom.id)
+<span class=3D"output">True</span>
+<span class=3D"prompt">>>></span> list(Person.selectBy(first_na=
me=3D<span class=3D"string">'John'</span>))
+<span class=3D"output">[]</span>
+</pre>
+
+</div>
+
+
+
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>Defining Classes</h1>
+
+<ul>
+ <li> The class name matches the table name </li>
+ <li> The attributes match the column names </li>
+ <li> (kind of...) </li>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>Defining Classes...</h1>
+
+<p>
+You can add extra methods:
+
+<pre>
+class Person(SQLObject):
+ ...
+ def _get_name(self):
+ return self.first_name + ' ' + self.last_name
+</pre>
+
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+<div class=3D"slide">
+<h1></h1>
+
+<ul>
+<li> <code>_get_attr()</code> methods are called whenever the
+<code>obj.attr</code> attribute is called </li>
+<li> <code>_set_attr()</code> methods are called whenever the
+<code>obj.attr =3D value</code> statement is run </li>
+<li> <code>_set_attr()</code> is optional </li>
+</ul>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>Defining classes...</h1>
+
+<p>
+You can override columns:
+
+<pre>
+class Person(SQLObject):
+ ...
+ last_name_searchable =3D StringCol()
+ def _set_last_name(self, value):
+ self._SO_set_last_name(self, value)
+ self.last_name_lower =3D re.sub(<span class=3D"string">r'[^a-zA-=
Z]'</span>, <span class=3D"string">''</span>, value).lower()
+</pre>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+<div class=3D"slide">
+<h1>Defining classes...</h1>
+
+<p>
+You can fiddle with the naming:
+
+<pre>
+class Person(SQLObject):
+ _table =3D <span class=3D"string">"people"</span>
+ first_name =3D StringCol(dbName=3D<span class=3D"string">"fname"</sp=
an>)
+ ...
+</pre>
+
+</p>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+<div class=3D"slide">
+<h1>Connecting classes</h1>
+
+<p>
+Foreign Keys:
+
+<pre>
+class Email(SQLObject):
+ person =3D ForeignKey(<span class=3D"string">'Person'</span>)
+ ...
+</pre>
+
+Note we use a string for <code class=3D"string">'Person'</code>.
+
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>Backreferences</h1>
+
+<p>
+The other side of one-to-many:
+
+<pre>
+class Person(SQLObject):
+ ...
+ emails =3D MultipleJoin(<span class=3D"string">'Email'</span>)
+</pre>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+<div class=3D"slide">
+<h1>Many-to-many</h1>
+
+<p>
+Many to many relationships imply a "hidden" table:
+
+<pre>
+class Address(SQLObject):
+ people =3D RelatedJoin(<span class=3D"string">'Person'</span>)
+ ...
+class Person(SQLObject):
+ addresses =3D RelatedJoin(<span class=3D"string">'Address'</span>)
+</pre>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+<div class=3D"slide">
+<h1>Lazy classes</h1>
+
+<p>
+SQLObject can use reflection to figure out what columns your table
+has:
+
+<pre>
+class Person(SQLObject):
+ _fromDatabase =3D True
+</pre>
+
+</p>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>Many-to-many...</h1>
+
+<p>
+The intermediate table created:
+
+<pre>
+CREATE TABLE address_person (
+ address_id INT NOT NULL,
+ person_id INT NOT NULL
+);
+</pre>
+</p>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>Instances</h1>
+
+<ul>
+<li>Use <code>Person.get(id)</code> to retrieve a row</li>
+<li>Use <code>Person(first_name=3D...)</code> to insert a row (the=20
+new object is returned)</li>
+<li>Use <code>aPerson.destroySelf()</code> to delete a row</li>
+</ul>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+<div class=3D"slide">
+<h1>Updating</h1>
+
+<ul>
+<li>Use <code>aPerson.first_name =3D <span
+class=3D"string">"new_name"</span></code></li>
+<li>Use <code>aPerson.set(first_name=3D<span
+class=3D"string">"new_fname"</span>, last_name=3D<span
+class=3D"string">"new_lname"</span>)</code> for multiple simultaneous
+updates. </li>
+</ul>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>Selecting</h1>
+
+<p>
+You can use Python expressions (kind of):
+
+<pre>
+query =3D Person.q.first_name =3D=3D <span class=3D"string">"Joe"</span>
+Person.select(query)
+</pre>
+
+</p>
+
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>Selecting...</h1>
+
+<p>
+
+<ul>
+<li><code>Class.<b>q</b>.<i>column_name</i></code> creates a magical
+object that creates queries.</li>
+<li><code>sqlrepr()</code> turns these query objects into SQL (mostly
+hidden)</li>
+<li><code>sqlrepr(Person.q.first_name =3D=3D <span
+class=3D"string">"Joe"</span>, <span class=3D"string">'mysql')</code>
+creates the SQL <code class=3D"sql">person.first_name =3D
+'Joe'</code></li>
+
+</p>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>Selecting...</h1>
+
+<p>
+Complicated joins are possible:
+
+<pre>
+Person.select((Person.q.id =3D=3D Email.q.personID)
+ & (Email.q.address.startswith('joe')))
+</pre>
+
+Becomes:
+
+<pre>
+SELECT person.id, person.first_name, person.last_name
+FROM person, email
+WHERE person.id =3D email.person_id
+ AND email.address LIKE 'joe%'
+</pre>
+
+</p>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+<div class=3D"slide">
+<h1>SelectResult</h1>
+
+Select results are fancy.
+
+<ul>
+<li> You can slice them, and <code class=3D"sql">LIMIT</code> and <code
+class=3D"sql">OFFSET</code> statements are added to your query</li>
+<li> You can iterate through them, and avoid loading all objects into
+memory</li>
+<li> You can do things like <code>select_result.count()</code> to run
+aggregate functions </li>
+<li> To get a real list, you must do <code>list(select_result)</code></l=
i>
+
+</ul>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>Caching</h1>
+
+<ul>
+<li>SQLObject caches everything</li>
+<li>Maybe too much (bad if you have multiple updaters)</li>
+<li>Needs to because there's no joins</li>
+<li>Has potential to be faster than ad hoc queries</li>
+<li>Thread safety or thread confusion?</li>
+</ul>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+<div class=3D"slide">
+<h1>Performance</h1>
+
+<ul>
+<li> Not good if you are dealing with lots and lots of rows </li>
+<li> Inserts and selects substantially slower </li>
+<li> But for many applications you'll pay that price sooner or later
+anyway </li>
+</ul>
+
+</div>
+
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>Solving the question by avoidance</h1>
+
+<ul>
+ <li> SQLObject doesn't let you forget SQL </li>
+ <li> You still have to think relationally </li>
+ <li> But many relational concepts don't work either </li>
+ <li> Advantage: it's easy </li>
+</ul>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>ORM Mismatch</h1>
+
+<ul>
+ <li> Python classes aren't tables</li>
+ <li> Python instances aren't rows</li>
+ <li> Primitive values (like <code class=3D"string">"John"</code>)
+ aren't part of the ORM at all </li>
+<ul>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>ORM Mismatch: Classes</h1>
+
+<ul>
+ <li> Databases don't have inheritance </li>
+ <li> Even when they do, no one uses it </li>
+ <li> Some tables are too boring (e.g., intermediate tables for
+ many-to-many relationships) </li>
+</ul>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+<div class=3D"slide">
+<h1>ORM Mismatch: Instances</h1>
+
+<ul>
+ <li> Instances get garbage collected, rows are forever </li>
+ <li> Instances can't be pre-allocated </li>
+ <li> In the relational calculus, rows don't have real identity </li>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>ORM Mismatch: Relations</h1>
+
+<ul>
+ <li> Things like joins don't make sense for objects, but are central
+ to relations </li>
+ <li> Views and stored procedures also don't make sense </li>
+</ul>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>Solving the Mismatch</h1>
+
+SQLObject's answer: don't try too hard.
+
+<ul>
+ <li> There exist database restrictions; not every database schema maps
+ well. (But most are fine) </li>
+ <li> There exist object restrictions; not every object-oriented
+ concept maps well; e.g., no inheritance. </li>
+</ul>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+
+</div>
+
+</body>
+</html>
Added: trunk/SQLObject/docs/presentation-2004-11/ui/bodybg.gif
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
(Binary files differ)
Property changes on: trunk/SQLObject/docs/presentation-2004-11/ui/bodybg.=
gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/SQLObject/docs/presentation-2004-11/ui/custom.css
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/SQLObject/docs/presentation-2004-11/ui/custom.css 2004-11-11 14=
:12:55 UTC (rev 348)
+++ trunk/SQLObject/docs/presentation-2004-11/ui/custom.css 2004-11-11 14=
:33:25 UTC (rev 349)
@@ -0,0 +1,39 @@
+.string {=20
+ color: #006600;
+}
+
+.comment {=20
+ color: #993300;
+}
+
+.output {=20
+ font-weight: bold;
+ color: #000066;
+}
+
+.prompt {=20
+ color: #000000;
+}
+
+.sql {=20
+ color: #006600;
+ font-weight: bold;
+}
+
+code {=20
+ color: #000066;
+ padding-left: 3px;
+ padding-right: 3px;
+ font-weight: bold;
+}
+
+pre {=20
+ margin-left: 7px;
+ padding: 3px;
+ border-left: 4px solid #666666;
+ background-color: #eeeeee;
+}
+
+tr.code-accent td, tr.code-accent th {=20
+ border: medium green dashed;
+}
\ No newline at end of file
Added: trunk/SQLObject/docs/presentation-2004-11/ui/framing.css
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/SQLObject/docs/presentation-2004-11/ui/framing.css 2004-11-11 1=
4:12:55 UTC (rev 348)
+++ trunk/SQLObject/docs/presentation-2004-11/ui/framing.css 2004-11-11 1=
4:33:25 UTC (rev 349)
@@ -0,0 +1,23 @@
+/* The following styles size, place, and layer the slide components.
+ Edit these if you want to change the overall slide layout.
+ The commented lines can be uncommented (and modified, if necessary)=20
+ to help you with the rearrangement process. */
+
+div#header, div#footer, div.slide {width: 100%; top: 0; left: 0;}
+div#header {top: 0; height: 3em; z-index: 1;}
+div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;}
+div.slide {top: 0; width: 92%; padding: 3.5em 4% 4%; z-index: 2;}
+div#controls {left: 50%; top: 0; width: 50%; height: 100%; z-index: 1;}
+#footer>div#controls {bottom: 0; top: auto; height: auto;}
+
+div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
+ margin: 0;}
+#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; z=
-index: 10;}
+html>body #currentSlide {position: fixed;}
+
+/*
+div#header {background: #FCC;}
+div#footer {background: #CCF;}
+div#controls {background: #BBD;}
+div#currentSlide {background: #FFC;}
+*/
Added: trunk/SQLObject/docs/presentation-2004-11/ui/opera.css
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/SQLObject/docs/presentation-2004-11/ui/opera.css 2004-11-11 14:=
12:55 UTC (rev 348)
+++ trunk/SQLObject/docs/presentation-2004-11/ui/opera.css 2004-11-11 14:=
33:25 UTC (rev 349)
@@ -0,0 +1,7 @@
+/* DO NOT CHANGE THESE unless you really want to break Opera Show */
+div.slide {
+ visibility: visible !important;
+ position: static !important;
+ page-break-before: always;
+}
+#slide0 {page-break-before: avoid;}
Added: trunk/SQLObject/docs/presentation-2004-11/ui/pretty.css
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/SQLObject/docs/presentation-2004-11/ui/pretty.css 2004-11-11 14=
:12:55 UTC (rev 348)
+++ trunk/SQLObject/docs/presentation-2004-11/ui/pretty.css 2004-11-11 14=
:33:25 UTC (rev 349)
@@ -0,0 +1,74 @@
+/* Following are the presentation styles -- edit away!
+ Note that the 'body' font size may have to be changed if the resoluti=
on is
+ different than expected. */
+
+body {background: #fff url(bodybg.gif) -16px 0 no-repeat; color: #000; f=
ont-size: 2em;}
+:link, :visited {text-decoration: none;}
+#controls :active {color: #88A !important;}
+#controls :focus {outline: 1px dotted #227;}
+h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inh=
erit;}
+ul, pre {margin: 0; line-height: 1em;}
+html, body {margin: 0; padding: 0;}
+
+blockquote, q {font-style: italic;}
+blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em; text-align: cen=
ter; font-size: 1em;}
+blockquote p {margin: 0;}
+blockquote i {font-style: normal;}
+blockquote b {display: block; margin-top: 0.5em; font-weight: normal; fo=
nt-size: smaller; font-style: normal;}
+blockquote b i {font-style: italic;}
+
+kbd {font-weight: bold; font-size: 1em;}
+sup {font-size: smaller; line-height: 1px;}
+
+code {padding: 2px 0.25em; font-weight: bold; color: #533;}
+code.bad, code del {color: red;}
+code.old {color: silver;}
+pre {padding: 0; margin: 0.25em 0 0.5em 0.5em; color: #533; font-size: 9=
0%;}
+pre code {display: block;}
+ul {margin-left: 5%; margin-right: 7%; list-style: disc;}
+li {margin-top: 0.75em; margin-right: 0;}
+ul ul {line-height: 1;}
+ul ul li {margin: .2em; font-size: 85%; list-style: square;}
+img.leader {display: block; margin: 0 auto;}
+
+div#header, div#footer {background: #005; color: #AAB;
+ font-family: Verdana, Helvetica, sans-serif;}
+div#header {background: #005 url(bodybg.gif) -16px 0 no-repeat;
+ line-height: 1px;}
+div#footer {font-size: 0.5em; font-weight: bold; padding: 1em 0;}
+#footer h1, #footer h2 {display: block; padding: 0 1em;}
+#footer h2 {font-style: italic;}
+
+div.long {font-size: 0.75em;}
+.slide h1 {position: absolute; top: 0.7em; left: 87px; z-index: 1;
+ margin: 0; padding: 0.3em 0 0 50px; white-space: nowrap;
+ font: bold 150%/1em Helvetica, sans-serif; text-transform: capitalize;
+ color: #DDE; background: #005;}
+.slide h3 {font-size: 130%;}
+h1 abbr {font-variant: small-caps;}
+
+div#controls {position: absolute; z-index: 1; left: 50%; top: 0;
+ width: 50%; height: 100%;
+ text-align: right;}
+#footer>div#controls {position: fixed; bottom: 0; padding: 1em 0;
+ top: auto; height: auto;}
+div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
+ margin: 0; padding: 0;}
+div#controls a {font-size: 2em; padding: 0; margin: 0 0.5em;=20
+ background: #005; border: none; color: #779;=20
+ cursor: pointer;}
+div#controls select {visibility: hidden; background: #DDD; color: #227;}
+div#controls div:hover select {visibility: visible;}
+
+#currentSlide {text-align: center; font-size: 0.5em; color: #449;}
+
+#slide0 {padding-top: 3.5em; font-size: 90%;}
+#slide0 h1 {position: static; margin: 1em 0 1.33em; padding: 0;
+ font: bold 2em Helvetica, sans-serif; white-space: normal;
+ color: #000; background: transparent;}
+#slide0 h3 {margin-top: 0.5em; font-size: 1.5em;}
+#slide0 h4 {margin-top: 0; font-size: 1em;}
+
+ul.urls {list-style: none; display: inline; margin: 0;}
+.urls li {display: inline; margin: 0;}
+.note {display: none;}
Added: trunk/SQLObject/docs/presentation-2004-11/ui/print.css
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/SQLObject/docs/presentation-2004-11/ui/print.css 2004-11-11 14:=
12:55 UTC (rev 348)
+++ trunk/SQLObject/docs/presentation-2004-11/ui/print.css 2004-11-11 14:=
33:25 UTC (rev 349)
@@ -0,0 +1 @@
+/* The next rule is necessary to have all slides appear in print! DO NOT=
REMOVE IT! */=0Ddiv.slide, ul {page-break-inside: avoid; visibility: vis=
ible !important;}=0Dh1 {page-break-after: avoid;}=0D=0Dbody {font-size: 1=
2pt; background: white;}=0D* {color: black;}=0D=0D#slide0 h1 {font-size: =
200%; border: none; margin: 0.5em 0 0.25em;}=0D#slide0 h3 {margin: 0; pad=
ding: 0;}=0D#slide0 h4 {margin: 0 0 0.5em; padding: 0;}=0D#slide0 {margin=
-bottom: 3em;}=0D=0Dh1 {border-top: 2pt solid gray; border-bottom: 1px do=
tted silver;}=0D.extra {background: transparent !important;}=0Ddiv.extra,=
pre.extra, .example {font-size: 10pt; color: #333;}=0Dul.extra a {font-w=
eight: bold;}=0Dp.example {display: none;}=0D=0D#header {display: none;}=0D=
#footer h1 {margin: 0; border-bottom: 1px solid; color: gray; font-style:=
italic;}=0D#footer h2, #controls {display: none;}=0D=0D#currentSlide {di=
splay: none;}
\ No newline at end of file
Added: trunk/SQLObject/docs/presentation-2004-11/ui/s5-core.css
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/SQLObject/docs/presentation-2004-11/ui/s5-core.css 2004-11-11 1=
4:12:55 UTC (rev 348)
+++ trunk/SQLObject/docs/presentation-2004-11/ui/s5-core.css 2004-11-11 1=
4:33:25 UTC (rev 349)
@@ -0,0 +1,9 @@
+/* Do not edit or override these styles! The system will likely break if=
you do. */
+
+div#header, div#footer, div.slide {position: absolute;}
+html>body div#header, html>body div#footer, html>body div.slide {positio=
n: fixed;}
+div.slide { visibility: hidden;}
+#slide0 {visibility: visible;}
+div#controls {position: absolute;}
+#footer>div#controls {position: fixed;}
+.handout {display: none;}
Added: trunk/SQLObject/docs/presentation-2004-11/ui/slides.css
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/SQLObject/docs/presentation-2004-11/ui/slides.css 2004-11-11 14=
:12:55 UTC (rev 348)
+++ trunk/SQLObject/docs/presentation-2004-11/ui/slides.css 2004-11-11 14=
:33:25 UTC (rev 349)
@@ -0,0 +1,3 @@
+@import url(s5-core.css); /* required to make the slide show run at all =
*/
+@import url(framing.css); /* sets basic placement and size of slide comp=
onents */
+@import url(pretty.css); /* stuff that makes the slides look better tha=
n blah */
Added: trunk/SQLObject/docs/presentation-2004-11/ui/slides.js
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/SQLObject/docs/presentation-2004-11/ui/slides.js 2004-11-11 14:=
12:55 UTC (rev 348)
+++ trunk/SQLObject/docs/presentation-2004-11/ui/slides.js 2004-11-11 14:=
33:25 UTC (rev 349)
@@ -0,0 +1,256 @@
+// S5 slides.js -- released under CC by-sa 2.0 license
+//
+// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for inf=
ormation=20
+// about all the wonderful and talented contributors to this code!
+
+var snum =3D 0;
+var smax =3D 1;
+var undef;
+var slcss =3D 1;
+var isIE =3D navigator.appName =3D=3D 'Microsoft Internet Explorer' ? 1 =
: 0;
+var isOp =3D navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0;
+var isGe =3D navigator.userAgent.indexOf('Gecko') > -1 && navigator.user=
Agent.indexOf('Safari') < 1 ? 1 : 0;
+var slideCSS =3D document.getElementById('slideProj').href;
+
+function isClass(object, className) {
+ return (object.className.search('(^|\\s)' + className + '(\\s|$)') !=3D=
-1);
+}
+
+function GetElementsWithClassName(elementName,className) {
+ var allElements =3D document.getElementsByTagName(elementName);
+ var elemColl =3D new Array();
+ for (i =3D 0; i< allElements.length; i++) {
+ if (isClass(allElements[i], className)) {
+ elemColl[elemColl.length] =3D allElements[i];
+ }
+ }
+ return elemColl;
+}
+
+function isParentOrSelf(element, id) {
+ if (element =3D=3D null || element.nodeName=3D=3D'BODY') return false;
+ else if (element.id =3D=3D id) return true;
+ else return isParentOrSelf(element.parentNode, id);
+}
+
+function nodeValue(node) {
+ var result =3D "";
+ if (node.nodeType =3D=3D 1) {
+ var children =3D node.childNodes;
+ for ( i =3D 0; i < children.length; ++i ) {
+ result +=3D nodeValue(children[i]);
+ } =09
+ }
+ else if (node.nodeType =3D=3D 3) {
+ result =3D node.nodeValue;
+ }
+ return(result);
+}
+
+function slideLabel() {
+ var slideColl =3D GetElementsWithClassName('div','slide');
+ var list =3D document.getElementById('jumplist');
+ smax =3D slideColl.length;
+ for (n =3D 0; n < smax; n++) {
+ var obj =3D slideColl[n];
+
+ var did =3D 'slide' + n.toString();
+ obj.setAttribute('id',did);
+ if(isOp) continue;
+
+ var otext =3D '';
+ var menu =3D obj.firstChild;
+ if (!menu) continue; // to cope with empty slides
+ while (menu && menu.nodeType =3D=3D 3) {
+ menu =3D menu.nextSibling;
+ }
+ if (!menu) continue; // to cope with slides with only text nodes
+
+ var menunodes =3D menu.childNodes;
+ for (o =3D 0; o < menunodes.length; o++) {
+ otext +=3D nodeValue(menunodes[o]);
+ }
+ list.options[list.length] =3D new Option(n+' : ' +otext,n);
+ }
+}
+
+function currentSlide() {
+ var cs;
+ if (document.getElementById) {
+ cs =3D document.getElementById('currentSlide');
+ } else {
+ cs =3D document.currentSlide;
+ }
+ cs.innerHTML =3D '<span id=3D"csHere">' + snum + '<\/span> ' +=20
+ '<span id=3D"csSep">\/<\/span> ' +=20
+ '<span id=3D"csTotal">' + (smax-1) + '<\/span>';
+ if (snum =3D=3D 0) {
+ cs.style.visibility =3D 'hidden';
+ } else {
+ cs.style.visibility =3D 'visible';
+ }
+}
+
+function go(inc) {
+ if (document.getElementById("slideProj").disabled) return;
+ var cid =3D 'slide' + snum;
+ if (inc !=3D 'j') {
+ snum +=3D inc;
+ lmax =3D smax - 1;
+ if (snum > lmax) snum =3D 0;
+ if (snum < 0) snum =3D lmax;
+ } else {
+ snum =3D parseInt(document.getElementById('jumplist').value);
+ }
+ var nid =3D 'slide' + snum;
+ var ne =3D document.getElementById(nid);
+ if (!ne) {
+ ne =3D document.getElementById('slide0');
+ snum =3D 0;
+ }
+ document.getElementById(cid).style.visibility =3D 'hidden';
+ ne.style.visibility =3D 'visible';
+ document.getElementById('jumplist').selectedIndex =3D snum;
+ currentSlide();
+}
+
+function toggle() {
+ var slideColl =3D GetElementsWithClassName('div','slide');
+ var obj =3D document.getElementById('slideProj');
+ if (!obj.disabled) {
+ obj.disabled =3D true;
+ for (n =3D 0; n < smax; n++) {
+ var slide =3D slideColl[n];
+ slide.style.visibility =3D 'visible';
+ }
+ } else {
+ obj.disabled =3D false;
+ for (n =3D 0; n < smax; n++) {
+ var slide =3D slideColl[n];
+ slide.style.visibility =3D 'hidden';
+ }
+ slideColl[snum].style.visibility =3D 'visible';
+ }
+}
+
+function showHide(action) {
+ var obj =3D document.getElementById('jumplist');
+ switch (action) {
+ case 's': obj.style.visibility =3D 'visible'; break;
+ case 'h': obj.style.visibility =3D 'hidden'; break;
+ case 'k':
+ if (obj.style.visibility !=3D 'visible') {
+ obj.style.visibility =3D 'visible';
+ } else {
+ obj.style.visibility =3D 'hidden';
+ }
+ break;
+ }
+}
+
+// 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/)
+function keys(key) {
+ if (!key) {
+ key =3D event;
+ key.which =3D key.keyCode;
+ }
+ switch (key.which) {
+ case 10: // return
+ case 13: // enter
+ if (window.event && isParentOrSelf(window.event.srcElement, "controls=
")) return;
+ if (key.target && isParentOrSelf(key.target, "controls")) return;
+ case 32: // spacebar
+ case 34: // page down
+ case 39: // rightkey
+ case 40: // downkey
+ go(1);
+ break;
+ case 33: // page up
+ case 37: // leftkey
+ case 38: // upkey
+ go(-1);
+ break;
+ case 84: // t
+ toggle();
+ break;
+ case 67: // c
+ showHide('k');
+ break;
+ }
+}
+
+function clicker(e) {
+ var target;
+ if (window.event) {
+ target =3D window.event.srcElement;
+ e =3D window.event;
+ } else target =3D e.target;
+ if (target.href !=3D null || isParentOrSelf(target, 'controls')) retur=
n true;
+ if (!e.which || e.which =3D=3D 1) go(1);
+}
+
+function slideJump() {
+ if (window.location.hash =3D=3D null) return;
+ var sregex =3D /^#slide(\d+)$/;
+ var matches =3D sregex.exec(window.location.hash);
+ var dest =3D null;
+ if (matches !=3D null) {
+ dest =3D parseInt(matches[1]);
+ } else {
+ var target =3D window.location.hash.slice(1);
+ var targetElement =3D null;
+ var aelements =3D document.getElementsByTagName("a");
+ for (i =3D 0; i < aelements.length; i++) {
+ var aelement =3D aelements[i];
+ if ( (aelement.name && aelement.name =3D=3D target)
+ || (aelement.id && aelement.id =3D=3D target) ) {
+ targetElement =3D aelement;
+ break;
+ }
+ }
+ while(targetElement !=3D null && targetElement.nodeName !=3D "body") {
+ if (targetElement.className =3D=3D "slide") break;
+ targetElement =3D targetElement.parentNode;
+ }
+ if (targetElement !=3D null && targetElement.className =3D=3D "slide")=
{
+ dest =3D parseInt(targetElement.id.slice(1));
+ }
+ }
+ if (dest !=3D null)
+ go(dest - snum);
+ }
+=20
+function createControls() {
+ controlsDiv =3D document.getElementById("controls");
+ if (!controlsDiv) return;
+ controlsDiv.innerHTML =3D '<form action=3D"#" id=3D"controlForm">' +
+ '<div>' +
+ '<a accesskey=3D"t" id=3D"toggle" href=3D"javascript:toggle();">Ø<=
\/a>' +
+ '<a accesskey=3D"z" id=3D"prev" href=3D"javascript:go(-1);">«<\/a=
>' +
+ '<a accesskey=3D"x" id=3D"next" href=3D"javascript:go(1);">»<\/a>=
' +
+ '<\/div>' +
+ '<div onmouseover=3D"showHide(\'s\');" onmouseout=3D"showHide(\'h\');">=
<select id=3D"jumplist" onchange=3D"go(\'j\');"><\/select><\/div>' +
+ '<\/form>';
+}
+
+function notOperaFix() {
+ var obj =3D document.getElementById('slideProj');
+ obj.setAttribute('media','screen');
+ if (isGe) {
+ obj.setAttribute('href','null'); // Gecko fix
+ obj.setAttribute('href',slideCSS); // Gecko fix
+ }
+}
+
+function startup() {
+ if (!isOp) createControls();
+ slideLabel();
+ if (!isOp) { =09
+ notOperaFix();
+ slideJump();
+ document.onkeyup =3D keys;
+ document.onclick =3D clicker;
+ }
+}
+
+window.onload =3D startup;
|